三数之和-算法题(双指针)

题目:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != 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] 。
注意,输出的顺序和三元组的顺序并不重要。

思路解析

**1.**题目中要求找到所有「不重复」且和为 000 的三元组。所以先进行一次排序。

2.可以发现,如果我们固定了前两重循环枚举到的元素 a和 b,那么只有唯一的 c 满足 a+b+c=0。当第二重循环往后枚举一个元素 b2时,由于 b2>b,那么满足 a+b2+c2=0 的 c2一定有 c2<c ,即c2在数组中一定出现在 c 的左侧。也就是说,我们可以从小到大枚举 b,同时从大到小枚举 c,即第二重循环和第三重循环实际上是可以合并的

就是双指针

3.完成上述步骤后,可以继续优化,比如减少循环中相同数字的重复查询

下面是完整代码,注释有写

java 复制代码
 public List<List<Integer>> threeSum(int[] nums) {
        int n =nums.length;
        Arrays.sort(nums);
        List<List<Integer>> answer =new ArrayList<>();
        for (int first =0;first <n;first++){
                // 需要和上一次枚举的数不相同
            if (first >0 && nums[first] == nums[first -1]){
                continue;
            }
            // c 对应的指针初始指向数组的最右端
            int cright =n-1;
            int target = -nums[first];// b+c 的值
            for(int second =first+1; second <n;second++){
                // 需要和上一次枚举的数不相同
                if (second >first+1 && nums[second] == nums[second -1]){
                    continue;
                }
                // 需要保证 b 的指针在 c 的指针的左侧
                while (second <cright && nums[second]+nums[cright]>target){
                    cright--;
                }
                // 如果指针重合,随着 b 后续的增加
                // 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if (second == cright) {
                    break;
                }
                if(nums[second]+nums[cright] == target){
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[cright]);
                    answer.add(list);
                }
            }
        }
        return answer;
    }
相关推荐
大厂码农老A2 分钟前
你打的日志,正在拖垮你的系统:从P4小白到P7专家都是怎么打日志的?
java·前端·后端
朝新_5 分钟前
【优选算法】第一弹——双指针(上)
算法
艾菜籽18 分钟前
Spring MVC入门补充2
java·spring·mvc
艾莉丝努力练剑27 分钟前
【C++STL :stack && queue (一) 】STL:stack与queue全解析|深入使用(附高频算法题详解)
linux·开发语言·数据结构·c++·算法
爆更小哇28 分钟前
统一功能处理
java·spring boot
程序员鱼皮30 分钟前
我造了个程序员练兵场,专治技术焦虑症!
java·计算机·程序员·编程·自学
CoovallyAIHub43 分钟前
ICLR 2026 惊现 SAM 3,匿名提交,实现“概念分割”,CV领域再迎颠覆性突破?
深度学习·算法·计算机视觉
IT古董1 小时前
【第五章:计算机视觉-计算机视觉在工业制造领域中的应用】1.工业缺陷分割-(2)BiseNet系列算法详解
算法·计算机视觉·制造
n8n1 小时前
SpringAI 完全指南:为Java应用注入生成式AI能力
java·后端
电鱼智能的电小鱼1 小时前
服装制造企业痛点解决方案:EFISH-SBC-RK3588 预测性维护方案
网络·人工智能·嵌入式硬件·算法·制造