首页 > 其他 > 详细

双指针:15. 三数之和

时间:2020-10-15 22:27:36      阅读:36      评论:0      收藏:0      [点我收藏+]

技术分享图片

 

 

这本来是做双指针的16题 最近三数之和,发现这个题目和著名的三数之和很像,所以就返回来先做这个了。

其实思路讲出来还蛮简单的。原本需要3轮for循环,但我们可以在第一轮for循环后,剩下的两重for循环采用排序+双指针的方式做,这样的话,时间复杂度由On3变为On2。

这里需要注意的是:

  • 二维ArrayList的创建添加还不是特别熟悉
  • 去重才是这题真正的难点,非常麻烦

去重需要从好几个地方考虑,如果i,j,k在移动时出现相等的值时都需要去重(不添加)

先看下我写的极其麻烦的代码:

import java.util.Arrays;
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result=new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++)//看这里具体是小于多少
        {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }//避免重复
            int targetNew=-nums[i];
            int j=i+1,k=nums.length-1;
            while(k>j)
            {
                if(nums[j]+nums[k]>targetNew)
                { k--;}
                else if(nums[j]+nums[k]<targetNew)
                {j++;}
                else if(nums[j]+nums[k]==targetNew)
                {
                    //避免重复
                    if(j==i+1)
                    {
                        if(k==nums.length-1)
                        {result.add(Arrays.asList(nums[i],nums[j],nums[k]));}
                        else
                        {
                            if(nums[k]!=nums[k+1])
                            {   
                                result.add(Arrays.asList(nums[i],nums[j],nums[k]));
                            }
                        }
                    }
                    else
                    {
                        if(k==nums.length-1)
                        {
                            if(nums[j]!=nums[j-1])
                            {   
                                result.add(Arrays.asList(nums[i],nums[j],nums[k]));
                            }
                        }
                        else
                        {
                            if(nums[k]!=nums[k+1]||nums[j]!=nums[j-1])
                            { result.add(Arrays.asList(nums[i],nums[j],nums[k]));}
                        }
                    }
                    k--;
                    j++;
                    //添加i,j,k这组到结果中
                }
            }
        }
        return result;
        

    }
}

主要是在双指针阶段,由于要判断 j和j-1是否相等,k和k+1是否相等,以及j-1是否越界,k+1是否越界,所以搞出来这个判断。

但实际上可以在出现一次正确结果时先尝试着移动指针,跳过那些可能的重复

import java.util.Arrays;
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result=new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++)//看这里具体是小于多少
        {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }//避免重复
            int targetNew=-nums[i];
            int j=i+1,k=nums.length-1;
            while(k>j)
            {
                if(nums[j]+nums[k]>targetNew)
                { k--;}
                else if(nums[j]+nums[k]<targetNew)
                {j++;}
                else if(nums[j]+nums[k]==targetNew)
                {
                    result.add(Arrays.asList(nums[i],nums[j],nums[k]));
                    j++;//注意要移动指针啊
                    k--;
                    while(j<k&&nums[j]==nums[j-1])//这里是去重的关键
                    {j++;}
                    while(k>j&&nums[k]==nums[k+1])
                    {k--;}
                }
            }
        }
        return result;
    }
}

 

双指针:15. 三数之和

原文:https://www.cnblogs.com/take-it-easy/p/13821056.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!