leetcode 15 三数之和 3Sum JAVA实现

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

注意:答案中不可以包含重复的三元组。

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

解法一:

穷举,时间复杂度为O(n3),会超时

解法二:

题目是求a+b+c=0,那么如果你用

for()

for()

for(){

a+b+c==0;

扫描二维码关注公众号,回复: 6186646 查看本文章

}

这是一个三数求和问题,

但是b+c=-a

因此,这就间接转化成了一个两数求和的问题。

因为要处理重复问题,因此将数组先排序,排序过后,取a = nums[i],则接下来在i+1 - len-1的范围寻找b和c使b和c满足b+c = -a;

假设nums = [-1, 0, 1, 2, -1, -4],

排序后nums=[-4,-1,-1,0,1,2];

当a = nums[i]时,则nums[len-1]为接下来最大的数,nums[i+1]为大于等于a的数。

如果nums[len-1] + nums[i+1]大于了a,那么b和c则只能出现在i+1 - <(len-1)的范围。

这和二分查找的思路很像,我们可以另a = nums[i] ,b = nums[i+1] ,c = nums[len-1]。

如果b+c>-a ,那么c往前移动

如果b+c<-a,那么a往后移动。

因为数组中有重复的数字,所以移动的时候要判断是否和移动前的数重复,如果重复,则应该继续移动。

对于nums=[-4,-1,-1,0,1,2];,当a = nums[1] = -1的时候,可以找到解{-1,0,1}。

当a = nums[2] = -1的时候,又可以找到解{-1,0,1}

这两个解重复了,与题目要求不符,那么排查重复的原因。

原因很显然是因为对于重复的a,那么如果有解,则必然会找到重复的解。

因此在i>=1的时候,判断nums[i] 是否和nums[i-1]相等,如果相等则跳过。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        
        List<List<Integer>> ans = new LinkedList<List<Integer>>();
        if(nums.length <= 2){
            return ans;   
        }
        Arrays.sort(nums);
        int len = nums.length;
        for(int i=0;i<len-2;i++){
            if(i==0 || (i>0 && nums[i]!=nums[i-1])){//去除重复的解
                int l = i+1,r=len-1,sum=0-nums[i];
                while(l<r){
                    if(nums[l]+nums[r]==sum){
                        ans.add(Arrays.asList(nums[i],nums[l],nums[r]));//找到一组解
                        while(l<r && nums[l] == nums[l+1]) l++;判断相等是为了 去除重复解 和减少不必要的查询情况
                        while(l<r && nums[r] == nums[r-1]) r--;
                        l++;
                        r--;
                    }else if(nums[l]+nums[r] <sum){
                        while(l<r && nums[l] == nums[l+1]) l++;
                        l++;
                    }else{
                        while(l<r && nums[r] == nums[r-1]) r--;
                        r--;
                    }
                }
            }
        }
        return ans;
        
    }
}

相关:

LeetCode16 3Sum Closest(最接近的三数之和) JAVA实现

LeetCode18. 四数之和 4Sum JAVA实现

猜你喜欢

转载自blog.csdn.net/qq_25406563/article/details/88035364