剑指 Offer II 007. 数组中和为 0 的三个数

100 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

一、题目描述:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。

 

示例 1:

输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 示例 2:

输入:nums = [] 输出:[] 示例 3:

输入:nums = [0] 输出:[]  

提示:

0 <= nums.length <= 3000 -105 <= nums[i] <= 105  

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/1f…

二、思路分析:

可以使用双指针的思想

具体思路如下: 先对数组进行从小到大排序; 从左到右遍历,对每一个位置i,我们在它右侧的区间内寻找结果; 因为i右侧的区间是单调的。设定左指针l=i+1,右指针r=end,对结果进行双指针查找。 题目要求不能有重复的结果,需要去重,手段如下: 当遍历的固定位置nums[i] === nums[i-1]时,可知结果重复,跳过; 当遍历的l值等于l-1位置的值,因为nums[i] = nums[l] + nums[r],

注意点: 1.每次固定i的时候需要判断nums[i]和nums[i-1]是否相等,以免找到相同的三元组 注意点: 2.每次找到三元组后,需要left++,这时候更新过的left所指的值和之前left所指的相同。需要判断

三、AC 代码:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int len = nums.length;
        if(len < 3) return res;
        Arrays.sort(nums);
        // 三元组的下标 i, j , k
        for(int i = 0; i < len-2; i++){
            int a = nums[i];
            int j = i + 1, k = len - 1;
            // 固定 a ,等价于 b + c 两数之和为 -a
            while(j < k){
                int b = nums[j], c = nums[k];
                if(a + b + c > 0){
                    k--;
                }else if (a + b + c < 0){
                    j++;
                }else{
                    res.add(Arrays.asList(a, b, c));
                    // 保证不重复的三元组
                    while(j < k && nums[j] == b){
                        j++;
                    }
                }
            }
            // 保证不重复的三元组
            while(i < len - 2 && nums[i + 1] == a){
                i++;
            }
        }
        return res;
    }
}

​

四、总结:

image.png 掘友们,解题不易,如果觉得有用就留下个赞或评论再走吧!谢啦~ 💐