From d5e902131a453d83b955383fc53edbb90830a844 Mon Sep 17 00:00:00 2001 From: kalyan Date: Sat, 8 Nov 2025 10:34:31 -0600 Subject: [PATCH] Backtracking-1 solutions --- CombinationSum.java | 71 ++++++++++++++++++++++++++++++++++++++++ ExpressionOperators.java | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 CombinationSum.java create mode 100644 ExpressionOperators.java diff --git a/CombinationSum.java b/CombinationSum.java new file mode 100644 index 00000000..f1184682 --- /dev/null +++ b/CombinationSum.java @@ -0,0 +1,71 @@ +// Time Complexity : O(2^(m+n)) where m is the length of candidates ad n is the target value. +// Space Complexity : O(n) +// Did this code successfully run on Leetcode : Yes +// Approach : I followed 0/1 recursion with backtracking and while the base condition is met, before storing the result we store a deep +// copy of it so that the rest of recursion happens without any issues. In no choose condition, index needs to be increased while in +// choose condition we dont have to increase index as it can have duplicates as well to reach the target sum. Once we find the result or we +// reach the end of the recursive function, we remove the last element in the path so that it can continue recursion. + + +class Solution { + List> result; + + public List> combinationSum(int[] candidates, int target) { + this.result = new ArrayList<>(); + helper(candidates, target, 0, new ArrayList<>()); + return result; + } + + private void helper(int[] candidates, int target, int index, List path) { + + if (target == 0) { + result.add(new ArrayList<>(path)); //copy of path + return; + } + if (target < 0 || index == candidates.length) { + return; + } + //no choose + helper(candidates, target, index + 1, path); + + //choose + path.add(candidates[index]); //add to path first + helper(candidates, target - candidates[index], index, path); + + //backtracking + path.remove(path.size() - 1); + } +} + + + +//for loop based recursion + +class Solution { + List> result; + + public List> combinationSum(int[] candidates, int target) { + this.result = new ArrayList<>(); + helper(candidates, target, 0, new ArrayList<>()); + return result; + } + + private void helper(int[] candidates, int target, int index, List path) { + + if (target == 0) { + result.add(new ArrayList<>(path)); //copy of path + return; + } + if (target < 0 || index == candidates.length) { + return; + } + + for (int i = index; i < candidates.length; i++) { + path.add(candidates[i]); + helper(candidates, target - candidates[i], i, path); + //backtracking + path.remove(path.size() - 1); + } + + } +} \ No newline at end of file diff --git a/ExpressionOperators.java b/ExpressionOperators.java new file mode 100644 index 00000000..7f86e9e2 --- /dev/null +++ b/ExpressionOperators.java @@ -0,0 +1,57 @@ +// Time Complexity : O(4^(n)) . +// Space Complexity : O(n) +// Did this code successfully run on Leetcode : Yes +// Approach : Used for loop recursion to solve this problem. First we need to achieve all possible combination of numbers and at each combination +// we have to calculate +,-,* for the combinations. We maintain a curr and tail values as we need higher precedence operator in * case +// by using the previous value. After exploring the path, we backtracking it and set the path length to previous step one. + + +class Solution { + List result; + public List addOperators(String num, int target) { + this.result = new ArrayList<>(); + helper(num, target, new StringBuilder(), 0, 0, 0); + return result; + } + + private void helper(String num, int target, StringBuilder path, int pivot, long calc, long tail){ + if(pivot == num.length()){ //base case + if(calc == target){ + result.add(path.toString()); + } + } + + for(int i = pivot; i < num.length(); i++){ + + if(num.charAt(pivot) == '0' && i != pivot) continue; // 0 precedence case + + long curr = Long.parseLong(num.substring(pivot, i+1)); + + int le = path.length(); + + if(pivot == 0){//at 0th level we dont have to perform operations + path.append(curr); + helper(num, target,path, i+1, curr, curr); + path.setLength(le);//backtrack + + }else{ + + // + case + path.append("+").append(curr); + helper(num, target, path, i+1, calc + curr, curr); + path.setLength(le);//backtrack + + // - case + path.append("-").append(curr); + helper(num, target, path, i+1, calc - curr, -curr); + path.setLength(le);//backtrack + + // * case + path.append("*").append(curr); + helper(num, target, path, i+1, calc - tail + (tail * curr), tail * curr); + path.setLength(le);//backtrack + } + } + } + +} \ No newline at end of file