LeetCode:3Sum_15

本文针对LeetCode中的3Sum问题提供了详细的解决方案。通过采用双指针技术优化了原始算法,解决了寻找数组中三个元素之和等于0的所有唯一组合的问题。文章还讨论了如何避免重复解并给出了具体的代码实现。

LeetCOde:3Sum

【问题再现】

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

【写在前面】

我试了很多方法尝试去解决这个问题,但是都无果。后来在一次算法课上讲到了这个问题,3Sum问题,当时讨论出的解决方法如下:

List<List<Integer>> mylist = new ArrayList<>();
            Arrays.sort(nums);
            for(int i=0;i<nums.length;i++) {
                for (int j = i+1;j<nums.length;j++) {
                    int k=Arrays.binarySearch(nums,-(nums[i]+nums[j]));
                    if(k>j)
                    {
                        ArrayList<Integer> al = new ArrayList<>();
                        al.add(nums[i]);al.add(nums[j]);al.add(nums[k]);
                        if(!mylist.contains(al))
                            mylist.add(al);
                    }
                }
            }
            return mylist;
}

当时我对这个结局方案非常满意,可是现在不这么认为了。如果给出的数组是[0,0,0,0],那么就无法解决。

因为第三个值为0,无论如何到找到的都是中间那个,K不可能大于J。何况J还在自增。但是无论如何这是我们思考后的东西,都是有价值的。

【优质算法】

    public List<List<Integer>> threeSum(int[] nums) {
        /*
            思路:从数组序列0开始依次取数作为第一个数字,剩下的两个数字指针从 数组的序列两端开始 相向取数字
                    并且每次都计算3个数的和,如为0则添加到列表,不为0,则根据和的大小,分别移动左右指针。
        
        */
        List<List<Integer>> result = new ArrayList<>();
        if(nums.length < 3) return result;
        Arrays.sort(nums);
        int i = 0;
        while(i < nums.length - 2) { 
            if(nums[i] > 0) break;
            
            int j = i + 1; //左指针
            int k = nums.length - 1; //右指针
            
            while(j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                if(sum == 0) result.add(Arrays.asList(nums[i], nums[j], nums[k]));
                if(sum <= 0) while(nums[j] == nums[++j] && j < k); //实现越过重复数字的功能
                if(sum >= 0) while(nums[k--] == nums[k] && j < k); //同样实现越过重复数字的功能
            }
            
            while(nums[i] == nums[++i] && i < nums.length - 2);//同上
        }
        return result;
    }

【题后反思】

  1.对 while循环的进一步理解:

    while(nums[i]=nums[++j]&&j<k)

     根据这条命令即可实现越过重复数字的功能.

  2.双指针技术的应用。   

 

转载于:https://www.cnblogs.com/MrSaver/p/5913336.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值