Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions combination_sum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Time Complexity : O(2^(m + n)) where m is candidates length and n is target
// Space Complexity : O(n)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No


// Your code here along with comments explaining your approach in three sentences only
// We use backtracking to explore two choices at every step: either include the current candidate or skip it and move to the next one.
// If the target becomes 0, we add a deep copy of the current path to the result since it forms a valid combination.
// Backtracking removes the last chosen element after recursion so other possible combinations can be explored correctly.

class Solution {
List<List<Integer>> result;
public List<List<Integer>> 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<Integer> path){
// Base case
if (target < 0 || index == candidates.length) return;

// Always return a deep copy
if (target == 0) {
result.add(new ArrayList<>(path));
return;
}

// don't choose
helper(candidates, target, index+1, path);

// choose
path.add(candidates[index]);
helper(candidates, target-candidates[index], index, path);

//backtrack
path.remove(path.size()-1);

}
}
80 changes: 80 additions & 0 deletions expression_add_operator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Time Complexity : O(4^n) cos 4 operations - noop, +, -, *
// Space Complexity : O(n)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No


// Your code here along with comments explaining your approach in three sentences only
// We use backtracking to try every possible number split and insert '+', '-', or '*' between numbers.
// The tail variable stores the previous operand so multiplication precedence can be handled by removing tail and adding tail * curr.
// We skip numbers with leading zeros and backtrack the StringBuilder after each recursive call to explore other expressions.

class Solution {
List<String> result;
public List<String> addOperators(String num, int target) {
this.result = new ArrayList<>();
helper(num, target, 0, 0l, 0l, new StringBuilder());
return result;

}

private void helper(String num, int target, int pivot, long calculated_value, long tail, StringBuilder path) {
// Base case
if (pivot == num.length()) {
if (calculated_value == target) {
result.add(path.toString());
}
return;
}

// Logic
for (int i = pivot; i < num.length(); i++) {
Long curr = Long.parseLong(num.substring(pivot, i+1));

// Preceding zero
if(num.charAt(pivot) == '0' && pivot!=i) {
continue;
}

int le = path.length();
// Top level
if (pivot == 0) {
// action
path.append(curr);
// recurse
helper(num, target, i+1, curr, curr, path);
//backtrack
path.setLength(le);
} else {
// +
// action
path.append("+");
path.append(curr);
// recurse
helper(num, target, i+1, calculated_value+curr, curr, path);
//backtrack
path.setLength(le);

// -
// action
path.append("-");
path.append(curr);
// recurse
helper(num, target, i+1, calculated_value-curr, -curr, path);
//backtrack
path.setLength(le);

// *
// action
path.append("*");
path.append(curr);
// recurse
helper(num, target, i+1, calculated_value-tail + curr*tail, curr*tail, path);
//backtrack
path.setLength(le);
}
}


}
}