|
| 1 | +# 3Sum |
| 2 | + |
| 3 | +Page on leetcode: https://leetcode.com/problems/3sum/ |
| 4 | + |
| 5 | +## Problem Statement |
| 6 | + |
| 7 | +Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. |
| 8 | + |
| 9 | +Notice that the solution set must not contain duplicate triplets. |
| 10 | + |
| 11 | +### Constraints |
| 12 | + |
| 13 | +- 3 <= nums.length <= 3000 |
| 14 | +- -10<sup>5</sup> <= nums[i] <= 10<sup>5</sup> |
| 15 | + |
| 16 | +### Example |
| 17 | + |
| 18 | +``` |
| 19 | +Input: nums = [-1,0,1,2,-1,-4] |
| 20 | +Output: [[-1,-1,2],[-1,0,1]] |
| 21 | +Explanation: |
| 22 | +nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0. |
| 23 | +nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0. |
| 24 | +nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0. |
| 25 | +The distinct triplets are [-1,0,1] and [-1,-1,2]. |
| 26 | +Notice that the order of the output and the order of the triplets does not matter. |
| 27 | +``` |
| 28 | + |
| 29 | +``` |
| 30 | +Input: nums = [0,1,1] |
| 31 | +Output: [] |
| 32 | +Explanation: The only possible triplet does not sum up to 0. |
| 33 | +``` |
| 34 | + |
| 35 | +``` |
| 36 | +Input: nums = [0,0,0] |
| 37 | +Output: [[0,0,0]] |
| 38 | +Explanation: The only possible triplet sums up to 0. |
| 39 | +``` |
| 40 | + |
| 41 | +## Solution |
| 42 | + |
| 43 | +- No duplicates of triplets (Can I exclude with a hashmap?) |
| 44 | +- Brute force possible with an O(n<sup>3</sup>) solution |
| 45 | +- Approach like two sum and store pairs as key's and remainder as values? |
| 46 | +- All possibilities is n<sup>3</sup> (aka a cube) Some of these are complimentary, how can we eliminate those so we don't have to calc twice? |
| 47 | + |
| 48 | +### Pseudocode Attempt |
| 49 | + |
| 50 | +1. Create map |
| 51 | +2. Create result |
| 52 | +3. Iterate thru nums with i |
| 53 | +4. Iterate thru nums with j = i + 1 |
| 54 | +5. Store 0 - nums[i] - nums[j] in map with [nums[i], nums[j], false] |
| 55 | +6. If found add to result and change to true, if true don't add to result |
| 56 | +7. return result |
| 57 | + |
| 58 | +### Initial Attempt |
| 59 | + |
| 60 | +```javascript |
| 61 | +const threeSum = function (nums) { |
| 62 | + const map = {}; |
| 63 | + const result = []; |
| 64 | + |
| 65 | + for (let i = 0; i < nums.length; i++) { |
| 66 | + for (let j = i + 1; j < nums.length; j++) { |
| 67 | + const remainder = 0 - nums[i] - nums[j]; |
| 68 | + if (remainder in map) { |
| 69 | + // Check if combo was already used |
| 70 | + if (!map[remainder][2]) { |
| 71 | + result.push([remainder, nums[i], nums[j]]); |
| 72 | + } |
| 73 | + } else { |
| 74 | + map[remainder] = [nums[i], nums[j], false]; |
| 75 | + } |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + return result; |
| 80 | +}; |
| 81 | +``` |
| 82 | + |
| 83 | +### Optimized Solution |
| 84 | + |
| 85 | +The time complexity of below is O(n<sup>2</sup>) with a space complexity likely O(n) due to the sorting. https://www.youtube.com/watch?v=jzZsG8n2R9A |
| 86 | + |
| 87 | +```javascript |
| 88 | +const threeSum = function (nums) { |
| 89 | + const result = []; |
| 90 | + nums.sort((a, b) => a - b); |
| 91 | + |
| 92 | + for (let i = 0; i < nums.length; i++) { |
| 93 | + // This is an optimization as it exits iterating over the sorted array when num[i] becomes positive. Only positive numbers would be left in the array and you can't add them to make zero |
| 94 | + if (nums[i] > 0) { |
| 95 | + break; |
| 96 | + } |
| 97 | + |
| 98 | + if (i > 0 && nums[i] === nums[i - 1]) { |
| 99 | + continue; |
| 100 | + } |
| 101 | + |
| 102 | + let l = i + 1; |
| 103 | + let r = nums.length - 1; |
| 104 | + while (l < r) { |
| 105 | + const total = nums[i] + nums[l] + nums[r]; |
| 106 | + if (total > 0) { |
| 107 | + r--; |
| 108 | + } else if (total < 0) { |
| 109 | + l++; |
| 110 | + } else { |
| 111 | + result.push([nums[i], nums[l], nums[r]]); |
| 112 | + l++; |
| 113 | + while (nums[l] === nums[l - 1] && l < r) { |
| 114 | + l++; |
| 115 | + } |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | + |
| 120 | + return result; |
| 121 | +}; |
| 122 | +``` |
0 commit comments