|
| 1 | +class Solution: |
| 2 | + def fourSum(self, nums: List[int], target: int) -> List[List[int]]: |
| 3 | + ''' |
| 4 | + Brute Force: Generate all possible quadruplets. Check if they sum to target. O(N^4) Time, O(1) Space. |
| 5 | + Optimal: Sort, Recursively reduce subproblem to Two Sum II, then solve that. |
| 6 | + We need to avoid duplicates in result. Best way to do that is to Sort. Then check if adjacent elements are equal while traversing array, and keep traversing if so. |
| 7 | + K-Sum can be reduced to 2-Sum by recursively looping through array, choosing current element (ignoring duplciates) to add to current subset sum, and calling K-1 Sum on the remainder of the array. |
| 8 | + Base Case: Once K = 2, we can find Two Sum for a sorted array via 2 Pointer strategy (See Two Sum II) |
| 9 | +
|
| 10 | + O(N^3) Time. Number of nodes per level of recursion tree = N (Each element in the array is selected during loop, like when building combinations.) Depth of recursion tree = 4 - 2 = 2. Base case Two Sum II is O(N). O(N^2) * O(N) = O(N^3) |
| 11 | + O(N) Space. Recursive call stack length is O(K) (keeps going until K Sum reduces to 2 Sum). Current subset array is at worst same size as input array O(N). |
| 12 | +
|
| 13 | + Mistake: No return statements needed. Just make result and current subset arrays outside recursive function, and backtrack appends to subset array after making the recursive call. |
| 14 | + Mistake: Don't forget that we have to ignore duplicates. Whenever we add an element to result or subset, compare to previous element and keep traversing if they're duplicates. |
| 15 | + ''' |
| 16 | + |
| 17 | + nums.sort() |
| 18 | + res, sumset = [], [] |
| 19 | + |
| 20 | + def kSum(k, target, start): |
| 21 | + if k == 2: |
| 22 | + l, r = start, len(nums)-1 |
| 23 | + while l < r: |
| 24 | + if nums[l] + nums[r] < target: |
| 25 | + l += 1 |
| 26 | + elif nums[l] + nums[r] > target: |
| 27 | + r -= 1 |
| 28 | + else: |
| 29 | + res.append(sumset + [nums[l], nums[r]]) |
| 30 | + l += 1 |
| 31 | + while l < r and nums[l] == nums[l-1]: |
| 32 | + l += 1 |
| 33 | + else: |
| 34 | + for i in range(start, len(nums)): |
| 35 | + if i > start and nums[i] == nums[i-1]: |
| 36 | + continue |
| 37 | + sumset.append(nums[i]) |
| 38 | + kSum(k-1, target - nums[i], i+1) |
| 39 | + sumset.pop() |
| 40 | + |
| 41 | + kSum(4, target, 0) |
| 42 | + return res |
0 commit comments