LeetCode 之 3sum

题目链接:3sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

这道题题意就是输出数组中三个数和为0的所有情况。
参考:https://www.cnblogs.com/springfor/p/3859670.html

注意重点:不能出现重复,所以如何处理重复是关键;

最直接简单的思路就是三重循环得出数组中3个数的所有组合情况,如果和为0则将其加入到List中,但是明显出现的问题有:1.时间复杂度为O(n^3),然后重复问题不太好解决(就是因为重复卡了半天)。

参考了其他人的思路,时间复杂度为O(n^2),解决思路:
1.首先将数组排序
2.从0—(len-3)遍历固定一个元素,在剩下的元素中使用两个指针分别从头尾进行扫面,运行2sum问题。
3.解决重复问题:(1)使用hashset
(2)因为是排序好了的,所以判断前后元素是否相同,如果相同则跳过

代码如下:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int len = nums.length;
        List<List<Integer>> re = new ArrayList<>();

        //处理特殊情况
        if(len<3)
            return re;

        //数组排序
        Arrays.sort(nums);
        int j = 0 , k = 0;

        for(int i = 0;i<len-2;i++){
            //当nums[i]!nums[i-1]时才进行2sum,用于去除重复
            if(i==0||nums[i]!=nums[i-1]){
                j = i+1;
                k = len-1;
                while(j<k){
                    if(nums[i]+nums[j]+nums[k]==0){
                        ArrayList<Integer> temp = new ArrayList<Integer>();
                        temp.add(nums[i]);
                        temp.add(nums[j]);
                        temp.add(nums[k]);
                        re.add(temp);
                        //同样用于去除重复
                        while(j<k && nums[j]==nums[j+1])
                            j++;
                        while(j<k && nums[k]==nums[k-1])
                            k--;

                        j++;
                        k--;
                     //因为是排序好的,所以当计算的和>0时,尾部指针移动;否则头部移动
                    }else if(nums[i]+nums[j]+nums[k]>0)
                        k--;
                    else
                        j++;
                }
            }
        }
        return re;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值