diff --git a/CombinationSum.py b/CombinationSum.py new file mode 100644 index 00000000..e2e36712 --- /dev/null +++ b/CombinationSum.py @@ -0,0 +1,59 @@ +# Time Complexity : O(2^(m+n)) where m is the length of candidates and n is the target +# Space Complexity : O(n) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No + +# The approach is to do exhaustive solution to find all the path that match the target. Once we find the target +# then add it to the result. + +class Solution: + def combinationSum01Recursion(self, candidates: List[int], target: int) -> List[List[int]]: + self.result = [] + self.helper(candidates, 0, [], target) + return self.result + + def helper(self, candidates, idx, path, target): + # Base case + if idx == len(candidates) or target < 0: + return + if target == 0: + self.result.append(list(path)) + return + # Logic + # 0 + self.helper(candidates, idx + 1, path, target) + # 1 + path.append(candidates[idx]) + self.helper(candidates, idx, path, target - candidates[idx]) + # backtracking + path.pop() + +# Time Complexity : O(2^(m+n)) where m is the length of candidates and n is the target +# Space Complexity : O(n) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No + +#Almost similar approach as 01 with backtracking. Here we run a loop with a pivot and then chose the candidates and add to the path +# and then subtract from the target for the next recursion step. + +class Solution: + def combinationSumIterativeRecursion(self, candidates: List[int], target: int) -> List[List[int]]: + self.result = [] + self.helper(candidates, 0, [], target) + return self.result + + def helper(self, candidates, pivot, path, target): + + if target < 0: + return + + if target == 0: + self.result.append(path.copy()) + + for i in range(pivot, len(candidates)): + # action + path.append(candidates[i]) + # recurse + self.helper(candidates, i, path, target - candidates[i]) + # backtrack + path.pop() \ No newline at end of file diff --git a/ExpressionAddOperators.py b/ExpressionAddOperators.py new file mode 100644 index 00000000..1b46d473 --- /dev/null +++ b/ExpressionAddOperators.py @@ -0,0 +1,88 @@ +# Time Complexity : O(4^n) nested recursion +# Space Complexity : O(n^2) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No + +# The approach is to split the numbers first and then for each number we have 3 options(+,- and *). +# To do the calculation as runtime, we can use calc and tail which is the previous change to have the consideration of multiplication +# as we have to give precedence to * before + and - + + +class Solution: + def addOperatorsRecursion(self, num: str, target: int) -> List[str]: + result = [] + + def helper(pivot, calc, tail, path): + + if pivot == len(num): + if target == calc: + result.append(path) + return + # logic + for i in range(pivot, len(num)): + # Preceding 0 + if (i != pivot and num[pivot] == '0'): continue + curr = int(num[pivot:i + 1]) + if (pivot == 0): + helper(i + 1, curr, curr, path + str(curr)) + else: + # three options + # + + helper(i + 1, calc + curr, +curr, path + "+" + str(curr)) + # - + helper(i + 1, calc - curr, -curr, path + "-" + str(curr)) + # * + helper(i + 1, calc - tail + tail * curr, tail * curr, path + "*" + str(curr)) + + helper(0, 0, 0, "") + + return result + +# The time and space complexity is same. Just a bit of optimization using the path as list and later join before adding it to the result +# Also because of that we have to do backtracking. +class Solution: + def addOperators(self, num: str, target: int) -> List[str]: + result = [] + + def helper(pivot, calc, tail, path): + # Base case + if pivot == len(num): + if target == calc: + result.append("".join(path)) + return + # logic + for i in range(pivot, len(num)): + # Preceding 0 + if (i != pivot and num[pivot] == '0'): continue + curr = int(num[pivot:i + 1]) + if (pivot == 0): + path.append(str(curr)) + helper(i + 1, curr, curr, path) + path.pop() + else: + # three options + # + + path.append("+") + path.append(str(curr)) + helper(i + 1, calc + curr, +curr, path) + path.pop() + path.pop() + # - + path.append("-") + path.append(str(curr)) + helper(i + 1, calc - curr, -curr, path) + path.pop() + path.pop() + # * + #action + path.append("*") + path.append(str(curr)) + #recurse + helper(i + 1, calc - tail + tail * curr, tail * curr, path) + #backtrack + path.pop() + path.pop() + + helper(0, 0, 0, []) + + return result \ No newline at end of file