LeetCode刷题笔记-15. 三数之和

题目:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
实例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

题解:
首先想到的思路是暴力法,但是三个元素遍历的话时间复杂度为O(n^3),很容易超时,所以我们可以想到把其中一个元素固定,然后用双指针法查找剩下数组元素中的两个符合条件的值,这样的话时间复杂度为O(n ^2)。
要用双指针法我们首先需要将数组排好序,磨刀不误砍柴工。然后遍历数组,我们遍历所找到的的元素 i 其实是是三元素中最小的元素,然后在[i+1,n-1]内用双指针寻找剩下两个元素,在真正的用双指针法之前,我们在判断num[i]时可以利用性质适当的舍去不可能存在解的情况:①如果num[i]>0,在最小元素都大于0的情况下我们不可能找到解;②如果存在重复元素,我们只考虑该元素首次出现时的情况,避免重复解;
然后令左指针 L=i+1,右指针 R=n−1,当 L<R 时,执行循环:
当nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解
若和大于 0,说明 nums[R] 太大,R左移;若和小于 0,说明 nums[L]太小,L右移。
代码如下:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> lists=new ArrayList<>();
        int len=nums.length;
        
        if(nums==null||len<3) return lists;
        Arrays.sort(nums);
        for(int i=0;i<len-2;i++){
            if(nums[i]>0) return lists;
            if(i>0){
                if(nums[i-1]==nums[i]) continue;
            }
            int now=nums[i];
            int left=i+1,right=len-1;
            while(right>left){
                int le=nums[left],ri=nums[right];
                int sum=le+ri+now;
                if(sum==0){
                    List list=new ArrayList();
                    list.add(now);
                    list.add(le);
                    list.add(ri);
                    lists.add(list);
                    while(left<right && nums[left+1]==le) left++;
                    while(left<right && nums[right-1]==ri) right--;
                    right--;
                    left++;
                }
                else if(sum>0) right--;
                else left++;
            }
        }
        return lists;
    }
}

大神题解

发布了10 篇原创文章 · 获赞 3 · 访问量 2262

猜你喜欢

转载自blog.csdn.net/qq_40397223/article/details/104863241