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;
    }
}
相关推荐
WWW65261 小时前
代码随想录 打卡第五十四天
数据结构·c++·算法
墨白曦煜1 小时前
算法实战笔记:空间换时间的黑魔法——单调栈全景解析(十一)
java·笔记·算法
大模型最新论文1 小时前
小红书提出 RedKnot:分头处理 kv 缓存,延时降低 60%效果还提升
算法
随意起个昵称1 小时前
线性dp-LIS题目6(友好城市,二分优化)
算法·动态规划
数据科学小丫1 小时前
算法:随机森林算法
算法·随机森林·机器学习
Samson Bruce1 小时前
【初高中数学】
线性代数·数学·算法·机器学习
redaijufeng1 小时前
我在C++中深入理解了继承,收获颇丰
java·c++·算法
Ricky05531 小时前
DEIM :采用改进匹配算法实现快速收敛的DETR(中国25年3月研究)
人工智能·算法·目标跟踪
无限码力1 小时前
美团研发岗 5月9号笔试真题 - 弹性分桶
算法·美团笔试题·美团研发岗笔试题·美团0509笔试题