15. 三数之和
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
今天看这道题目,思路是排序+双指针,通过k固定一个元素,然后两个i,j索引分别从数组两端向中间遍历寻找nums[k] + nums[i] + nums[j] = 0的三元组
class Solution {public List<List<Integer>> threeSum(int[] nums) {//对数组进行排序处理Arrays.sort(nums);//用于存放符合要求的三元组List<List<Integer>> res = new ArrayList<List<Integer>>();//定义双指针,其实就是数组的下标,分别记录数组两端位置的下标int sum = 0, i = 0, j = 0;//假设三元组分别表示为 nums[k]、nums[i]、nums[j]//nums[k] 为固定第一个元素,k可以取值范围为[0, nums.length - 3], 为什么不能取nums.length - 2 和 nums.length - 1呢?//因为nums.length - 2 和 nums.length - 1要留给第二个元素nums[i]和第三个元素nums[j]取for (int k = 0; k < nums.length - 2; k++) {i = k + 1;j = nums.length - 1;//如果nums[k]都大于零,那么其右侧的元素肯定都大于0,也就不存在三数之和为0的三元组了,直接退出循环if (nums[k] > 0) break;//固定元素nums[k]不能重复,遇到重复的跳过if (k > 0 && nums[k] == nums[k - 1]) continue;//固定其中一个元素后,用两个指针i和j去遍历其右侧元素,直到寻找到符合要求的三元组while (i < j) {sum = nums[k] + nums[i] + nums[j];if (sum < 0) {//sum < 0 说明nums[i]太小了,往右边移动,遇到重复跳过while (i < j && nums[i] == nums[++i]);} else if (sum > 0) {//sum > 0 说明nums[j]太大了,往左边移动,遇到重复跳过while (i < j && nums[j] == nums[--j]);} else {//符合要求,添加进集合中res.add(new ArrayList<>(Arrays.asList(nums[k], nums[i], nums[j])));//分别移动i和j指针,遇到重复跳过while (i < j && nums[i] == nums[++i]);while (i < j && nums[j] == nums[--j]);}}}return res;}
}
题目链接:题单 - 力扣(LeetCode)全球极客挚爱的技术成长平台