LeetCodeHot100——15.三数之和

题目的链接:15. 三数之和 - 力扣(LeetCode)

这道题的意思就是找出给定数组nums中,和为0的三数字组合,之前我们在做两数之和的时候使用了Set的性质来做,但是三个的时候就无法通过一对一的关系找元素了,所以我们要换一种思路来做,从双指针来入手做这个题;

首先我们要明确双指针分别指的是什么,这道题我就直接给出我的思路了,由于是三个数字的组合,假如我们像之前的题目那样,一个指针负责遍历,一个指针负责操作的话那很明显指针是不够用的,但是我们遍历数组又是很有必要的,所以我们两个指针都是用于指向一次遍历中的临时位置的,我们这里规定左指针指向遍历到的当前的位置+1的位置,右指针指向nums的最后一个元素,然后在一次遍历当中我们移动两个指针来实现判断当前位置是否有符合条件的一组数字组合,但是我们如果直接进行判断的话就会造成两个指针的移动需要覆盖所有情况(因为是无序的,所以为了不漏查必须所有组合全判断一遍),最坏的情况下时间复杂度直逼O(n2),所以我们就在处理的最初给nums先排序,使用Java中的Arrays.sort(int nums)排序就行,排序之后就可以简化操作了,可能遇到的情况如下:

(1)当前值+左值+右值==0,加入到结果集中;

(2)当前值+左值+右值>0,由于排好序了所以我们就向左移动右指针;

(3)当前值+左值+右值<0,由于排好序了所以我们就向右移动左指针;

移动指针之后我们为了节省不必要的开销,和防止结果集中出现重复元素,我们可以在移动指针之后进行去重操作,例如我要移动的是左指针,我就搞一个while来对于他右边(下一次要移动的位置)判断是否和当前的值一样,如果一样就在while中给左指针推到最后一个当前值的位置(111最后一个1)再移动指针,这样就可以确保移动之后的值一定指向新的值,得出的三数之和也一定是新值,同时我们也可以对主遍历进行去重,也是和上面一样的道理,其实我们还可以减少开销,就是在每次主遍历开始的时候如果主遍历当前的值>0之后那必然左右指针也大于0,所以也就必然不会出现满足条件的组合了,最后附上我的做法:

java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums == null || nums.length == 0){
            return res;
        }
        Arrays.sort(nums);
        for(int i = 0;i<nums.length-2;i++){
            if(nums[i]>0){
                return res;
            }
            if(i>0&&nums[i]==nums[i-1]){
                continue;
            }
            int left = i+1;
            int right = nums.length-1;
            while(left < right){
                int curSum = nums[left]+nums[right]+nums[i];
                if(curSum == 0){
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[i]);
                    temp.add(nums[left]);
                    temp.add(nums[right]);
                    res.add(temp);
                    while(left<right&&nums[left]==nums[left+1]){
                        left++;
                    }
                    while(left<right&&nums[right]==nums[right-1]){
                        right--;
                    }
                    left++;
                    right--;
                }else if(curSum < 0){
                    left++;
                }else{
                    right--;
                }
            }
        }
        return res;
    }
}
相关推荐
北域码匠25 分钟前
高通滤波算法深度解析(High-Pass Filter)
stm32·算法·c#·数字信号处理·嵌入式开发·滤波算法·高通滤波
指掀涛澜天下惊1 小时前
强化学习进阶篇八 策略梯度算法
深度学习·学习·算法·强化学习
乌萨奇也要立志学C++1 小时前
【洛谷】kmp算法
开发语言·算法
禹凕1 小时前
Dijkstra算法详解与应用
python·算法
YaraMemo2 小时前
元启发式算法框架
人工智能·算法·5g·信息与通信·启发式算法·信号处理
weixin_307779132 小时前
一维无粘 Burgers 方程的激波形成问题:MacCormack 格式求解
c++·算法·matlab
HugoStudio_SWAN3 小时前
洛谷 B4500 / B4449 / B3843 凯撒密码、密码强度与密码合规——加密与安全的三道门
c++·学习·程序人生·算法·安全
枫叶林FYL4 小时前
【群体智能集群控制工程实践】第3章 一致性协同算法
算法
禹凕4 小时前
滑动窗口算法实战指南
python·算法
DisonTangor4 小时前
【腾讯混元雪耻归来】 Hy4 preview:770B 参数 MoE 旗舰模型,1M 上下文全面开源
人工智能·算法·开源·aigc·腾讯云·腾讯云ai代码助手