# NOTE: Far from the most optimal solution to the problem. # Time complexity: O(n^3) # Space complexity: O(n^2) // NOTE: Really? And how? class Solution: def fourSum(self, nums: List[int], target: int) -> List[List[int]]: arr_len = len(nums) # Helps keep out duplicates nums.sort() # Will be a dict with each key storing a `set` of 2-tuples (pair of nums) diff_cache = {} quadruplets = set() # No point in iterating with the last element since we won't be adding # any new quadruplets at that point for i in range(1, arr_len - 1): for j in range(i + 1, arr_len): current_sum = nums[i] + nums[j] difference = target - current_sum if difference in diff_cache: # diff_cache could have multiple pairs that add up to the same # `difference`. We need to form quadruplets with all of them # and store them in `quadruplets` for pair in diff_cache[difference]: quadruplets.add(pair + (nums[i], nums[j])) # Compute sum with every element to the left of i and store # in diff_cache. We do this at this later point to avoid duplicates for k in range(0, i): current_sum = nums[i] + nums[k] if current_sum in diff_cache: diff_cache[current_sum].add((nums[i], nums[k])) else: # This has to be a set to avoid duplicates diff_cache[current_sum] = { (nums[i], nums[k]) } return quadruplets