题目一
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.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
思路
如果数组是无序的,很难有比O(N3)更好的办法。除非是用哈希表,在得到两个数之和之后,在表中O(1)时间内寻找第三个数,总体复杂度也是O(n2),但需要O(n)的空间。
如果先将数组排序O(nlogn),然后固定第一个数,在后面的部分用TwoSum和数组递增的思想,来搜索。总体时间复杂度为O(nlogn+n2)
需要注意的是最后结果中不能有重复的。
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; int len = nums.size(); if (len <= 2) return res; sort(nums.begin(), nums.end()); int i = 0; while (i < len) { int start = i + 1; int end = len - 1; while (start < end) { if (nums[i] + nums[start] + nums[end] == 0){ res.push_back({nums[i], nums[start], nums[end]}); start++; end--; while (start < end && nums[start] == nums[start-1]) start++; while (start < end && nums[end] == nums[end+1]) end--; } else if (nums[i] + nums[start] + nums[end] > 0) end--; else start++; } i++; // 防止重复,不能删去 while (i < len && nums[i] == nums[i-1]) i++; } return res; } };
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; int len = nums.size(); if (len <= 2) return res; sort(nums.begin(), nums.end()); int i = 0; for (int i = 0; i < len - 2; i++) { if (i == 0 || nums[i] != nums[i-1]) { int start = i + 1; int end = len - 1; while (start < end) { if (nums[i] + nums[start] + nums[end] == 0){ res.push_back({nums[i], nums[start], nums[end]}); start++; end--; while (start < end && nums[start] == nums[start-1]) start++; while (start < end && nums[end] == nums[end+1]) end--; } else if (nums[i] + nums[start] + nums[end] > 0) end--; else start++; } } } return res; } };
题目二
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.
Example:
Given array nums = [-1, 2, 1, -4], and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
思路
整体框架和题目一差不多,只需要多一个变量来记录当前的 sum-target 是否比之前的更小即可。
class Solution { public: int threeSumClosest(vector<int>& nums, int target) { int len = nums.size(); int res = nums[0] + nums[1] + nums[len - 1]; sort(nums.begin(), nums.end()); for (int i = 0; i < len - 2; i++) { int start = i + 1, end = len - 1; while (start < end) { int sum = nums[i] + nums[start] + nums[end]; if (sum > target) end--; else start++; if (abs(sum - target) < abs(res - target)) res = sum; } } return res; } };