15. 3Sum
给定一个无序数组,求数组中满足三个元素之和 = 0 的答案。
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路:
由于数组是无序的所以先将其排成有序的数组,利用一个 for 循环,当做三个元素中的 起始元素,remain = 0-nums[i],然后用 双标记法, l = i+1, r = n-1, 如果 nums[l] + nums[r] < remain ,则 l++, 如果 > remain, 则 r--, 相等就将其放入答案中。因为数组是有序的,且 r = n-1,所以如果 nums[l] + nums[r] < remain,只能是 l 移动,因为 r 已经是最大的了,不能再往右移了,同理,> remain时,只能移动 r 。但是要注意的是,答案不能重复,所以对于重复项,比如 [-1,-1,0,1],只能有 一个[-1,0,1],要注意判别筛选。
vector<vector<int>> threeSum(vector<int>& nums) { sort(nums.begin(), nums.end());//先排序 vector<vector<int>> res; int n = nums.size(); for (int i = 0; i < n-2; i++) { if (i > 0 && nums[i] == nums[i - 1]) continue;//已知相等的跳过 int l = i + 1, r = n - 1, remain = 0 - nums[i]; if (nums[i] > 0) break; while (l < r) { if (l > (i + 1) && nums[l] == nums[l - 1]) {//已知相等的跳过 l += 1; continue; } if (nums[l] + nums[r] < remain) l += 1; else if (nums[l] + nums[r] > remain) r -= 1; else res.push_back({ nums[i],nums[l++],nums[r--] });//加入答案集后也要变动 l,r,否则死循环 } } return res; }
Java 版:
class Solution { public List<List<Integer>> threeSum(int[] nums) { int n = nums.length; List<List<Integer>> ans = new ArrayList<>(); Arrays.sort(nums); for(int i = 0; i < n; i++){ if(nums[i] > 0) break; if(i > 0 && nums[i-1] == nums[i]) continue; //判断是否重复 int remain = 0 - nums[i], l = i + 1, r = n-1; while(l < r){ if(nums[l] + nums[r] > remain) r--; else if(nums[l] + nums[r] < remain) l++; else { if(l-1 > i && nums[l-1] == nums[l]){ //判断是否重复 l++;continue; } ans.add(Arrays.asList(nums[i], nums[l++], nums[r])); } } } return ans; } }