1. Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Method 1: Using sorting + collision pointer, time complexity O(nlogn), space complexity O(1)
vector<int> twoSum(vector<int>& nums, int target) { vector<int> res; int i = 0, j = nums.size() - 1; while(left < right) { if(nums[i] + nums[j] == target) { res.push_back({i, j}); break; } else if(nums[i] + nums[j] < target) i ++; else j --; } return res; }
Method 2: Space for Time, Time Complexity O(n), Space Complexity O(n)
vector<int> twoSum(vector<int>& nums, int target) { map<int, int> mp; vector<int> res; for(int i = 0; i < nums.size(); i++) { if(mp.find(target - nums[i]) != mp.end()) { res= {mp[target- nums[i]], i}; break; } else mp[nums[i]] = i; } return res; }
15. 3Sum
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Method: Outer cycle + 2sum, attention to weight removal, time complexity O(n^2), space complexity O(1)
vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; if(nums.size() < 3) return res; sort(nums.begin(), nums.end()); for(int i = 0; i < nums.size() - 2; i ++) { if(i > 0 && nums[i] == nums[i - 1]) continue; int left = i + 1, right = nums.size() - 1; while(left < right) { if(nums[left] + nums[right] == -nums[i]) { vector<int> result = {nums[i], nums[left ++], nums[right --]}; res.push_back(result); while(left < right && nums[left] == nums[left-1]) left++; while(left < right && nums[right] == nums[right+1]) right--; } else if(nums[left] + nums[right] > -nums[i]) right --; else left ++; } } return res; }
16. 3Sum Closest
Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Method: Similar to 3sum, it can be free of duplication, time complexity O(n^2), space complexity O(1)
int threeSumClosest(vector<int>& nums, int target) { int res = 0; int mgap = INT_MAX; sort(nums.begin(), nums.end()); for(int i = 0; i < nums.size() - 2; i ++) { int j = i + 1; int k = nums.size() - 1; while(j < k) { int gap = abs(nums[i] + nums[j] + nums[k] - target); if(gap < mgap) { res = nums[i] + nums[j] + nums[k]; mgap = gap; } if(nums[i] + nums[j] + nums[k] < target) j ++; else k --; } } return res; }
18. 4Sum
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a+ b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
The solution set must not contain duplicate quadruplets.
Method: Double-layer cycle + 2sum, attention to weight removal, time complexity O(n^3), space complexity O(1)
vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> res; if(nums.size() < 3) return res; sort(nums.begin(), nums.end()); for(int j = 0; j <nums.size() - 3; j ++) { if(j > 0 && nums[j] == nums[j - 1]) continue; for(int i = j + 1; i < nums.size() - 2; i ++) { if(i > j + 1 && nums[i] == nums[i - 1]) continue; int left = i + 1, right = nums.size() - 1; while(left < right) { if(nums[left] + nums[right] == target-nums[i]-nums[j]) { vector<int> result = {nums[j], nums[i], nums[left ++], nums[right --]}; res.push_back(result); while(left < right && nums[left] == nums[left-1]) left++; while(left < right && nums[right] == nums[right+1]) right--; } else if(nums[left] + nums[right] > target-nums[i]-nums[j]) right --; else left ++; } } } return res; }
454. 4Sum II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.
To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 2^31 - 1.
Method: 2sum+2sum, recording the value of 2sum, time complexity O(n^2), space complexity O(n^2)
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { if(A.size() == 0) return 0; int res = 0; int N = A.size(); unordered_map<int, int> mp; for(int i = 0; i < N; i ++) for(int j = 0; j < N; j++) mp[A[i] + B[j]] ++; for(int i = 0; i < N; i ++) for(int j = 0; j < N; j ++) { if(mp.find(-C[i]-D[j]) != mp.end()) res += mp[-C[i]-D[j]]; } return res; }
summary
1. Pointer collision after sorting.
2. Change space for time and use hashmap to store intermediate results.