From c3fcec4dc6cacffe4e2458360b680b4c9012f33c Mon Sep 17 00:00:00 2001 From: Manideep Pilli Date: Wed, 26 Nov 2025 11:27:48 -0700 Subject: [PATCH] Completed Backtracking-1 --- _282_Expression_Add_Operators.java | 123 +++++++++++++++++++++++++++++ _39_Combination_Sum.java | 74 +++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 _282_Expression_Add_Operators.java create mode 100644 _39_Combination_Sum.java diff --git a/_282_Expression_Add_Operators.java b/_282_Expression_Add_Operators.java new file mode 100644 index 00000000..3d154889 --- /dev/null +++ b/_282_Expression_Add_Operators.java @@ -0,0 +1,123 @@ +/**** Method 1 ****/ +//Time Complexity: O((4^n)*n) +//Space Complexity: O(n^2) + +//Successfully submitted in LeetCode + +//To solve this problem, we store prev, with last completed operation and index, calculated values and string to hold the operations string. As we can partition the number at any index we take loop and run through all the partitions, and at each partition we have three options +,- and *, we perform the calculations, and when it *, as we can't directly do * as it will be left to right, we subtract the previous value from and add prev*curr, and store the previous as prev*curr as this will be helpful if there are consecutive *. For index is at 0 we don't have two numbers to perform operations, we just include the starting indexs and continue with recursion. Also to avoid forming leading 0's we check if there are more than one consecutive zero and break if true. For base condition, we check we have reached at end of the string and the calculated value is equals to target then add it ans list. + +/**** Method 2 ****/ +//Time Complexity: O(4^n) +//Space Complexity: O(n) + +//Successfully submitted in LeetCode + +// Same process as above but we use backtracking with help of string builder by appending before recursive call and removing it after the call. This is decreases the time complexity as string operations are expensive. + +import java.util.ArrayList; +import java.util.List; + +public class _282_Expression_Add_Operators { + + public List addOperators(String num, int target) { + ArrayList list = new ArrayList<>(); + + helper(num, 0, target, 0, 0, "", list); + + return list; + } + + private void helper( + String num, + int index, + int target, + long cal, + long prev, + String str, + ArrayList list + ) { + if (index == num.length()) { + if (target == cal) { + list.add(str); + } + } + + for (int i = index; i < num.length(); i++) { + if (num.charAt(index) == '0' && i != index) break; + long curr = Long.parseLong(num.substring(index, i + 1)); + + if (index == 0) { + helper(num, i + 1, target, curr, curr, str + curr, list); + } else { + helper(num, i + 1, target, cal + curr, curr, str + "+" + curr, list); + helper(num, i + 1, target, cal - curr, -curr, str + "-" + curr, list); + helper( + num, + i + 1, + target, + cal - prev + (prev * curr), + prev * curr, + str + "*" + curr, + list + ); + } + } + } + + public List addOperators1(String num, int target) { + ArrayList list = new ArrayList<>(); + + helper1(num, 0, target, 0, 0, new StringBuilder(), list); + + return list; + } + + private void helper1( + String num, + int index, + int target, + long cal, + long prev, + StringBuilder stb, + ArrayList list + ) { + if (index == num.length()) { + if (target == cal) { + list.add(stb.toString()); + } + } + + for (int i = index; i < num.length(); i++) { + if (num.charAt(index) == '0' && i != index) break; + String s = num.substring(index, i + 1); + long curr = Long.parseLong(s); + + int le = stb.length(); + if (index == 0) { + stb.append(s); + helper1(num, i + 1, target, curr, curr, stb, list); + stb.setLength(le); + } else { + stb.append("+").append(s); + helper1(num, i + 1, target, cal + curr, curr, stb, list); + stb.setLength(le); + + stb.append("-").append(s); + helper1(num, i + 1, target, cal - curr, -curr, stb, list); + stb.setLength(le); + + stb.append("*").append(s); + helper1( + num, + i + 1, + target, + cal - prev + (prev * curr), + prev * curr, + stb, + list + ); + stb.setLength(le); + } + } + } +} diff --git a/_39_Combination_Sum.java b/_39_Combination_Sum.java new file mode 100644 index 00000000..0951d3d2 --- /dev/null +++ b/_39_Combination_Sum.java @@ -0,0 +1,74 @@ +/**** Method 1 ****/ +//Time Complexity: O(2^(m+n)) m is candidate's length and n is target +//Space Complexity: O(n) + +//Successfully submitted in LeetCode + +// Using recursion we traverse using loop and add the value at the index to list and subtract it from target, after coming back from the recursion we remove the last added value and continue with the loop, for base the condition we any moment the target becomes zero, then we found a answer we add it the ans list. To avoid duplicates we ignore if the value at index is equal to previous value. + +/**** Method 2 ****/ +//Time Complexity: O(2^(m+n)) m is candidate's length and n is target +//Space Complexity: O(n) + +//Successfully submitted in LeetCode + +// Same as above but we use pick and no pick method instead of the loop. + +import java.util.ArrayList; +import java.util.List; + +public class _39_Combination_Sum { + + public List> combinationSum(int[] candidates, int target) { + List> ans = new ArrayList<>(); + List list = new ArrayList<>(); + combinationSum1(candidates, 0, target, list, ans); + return ans; + } + + public void combinationSum( + int candidates[], + int i, + int target, + List list, + List> ans + ) { + if (target == 0) { + ans.add(new ArrayList<>(list)); + return; + } + for (int idx = i; idx < candidates.length; idx++) { + if (idx < i && candidates[i - 1] == candidates[i]) continue; // to remove duplicates + if (candidates[idx] > target) continue; + list.add(candidates[idx]); + combinationSum(candidates, idx, target - candidates[idx], list, ans); + list.remove(list.size() - 1); + } + } + + public void combinationSum1( + int candidates[], + int i, + int target, + List list, + List> ans + ) { + if (i == candidates.length && target == 0) { + ans.add(new ArrayList<>(list)); + return; + } + + if (i == candidates.length || target < 0) { + return; + } + + list.add(candidates[i]); + combinationSum1(candidates, i, target - candidates[i], list, ans); + list.remove(list.size() - 1); + int j = i; + while (j < candidates.length && candidates[j] == candidates[i]) { + j++; + } + combinationSum1(candidates, j, target, list, ans); + } +}