题解 | #三数之和#

三数之和

http://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711

思路: 这题是两数之和为某个值的改版,首先要理解两数之和为target的解法,然后在此基础上这题就好理解了。

思路1:因为题目要求不能重复,所以可以先对数组排序,然后三指针法暴力遍历数组解决,时间复杂度为O(nlog2n)+O(n3)=O(n3)。但思考上面的过程发现排序只是用来去除相同的解,没能利用到升序的特性,所以优化可得到思路2.

思路2:可以想到先遍历数组,同时找基准值,然后每个基准值就相当于target,利用双指针法,一个指向基准值的后一个元素,一个指向数组尾端,二者之和为sum,若sum>target,右指针左移(说明此时和太大,需要减小sum,就需要一个更小的数),若小于,左指针右移,相等就加入结果List中,这次时间复杂度满足要求。

代码:

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
        //思路2,先排序,然后指定一个基准值作为target,从它的右边利用找两个数和为它
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        Arrays.sort(num);
        for(int i=0,len=num.length;i<len-2;i++){
            if(i>0&&num[i]==num[i-1]){
                continue;
            }
            findTarget(num,res,-num[i],i);
        }
        return res;
//         //思路1,先排序再三指针暴力法解决,不满足时间复杂度,但可以通过
//         ArrayList<ArrayList<Integer>> res=new ArrayList<>();
//         Arrays.sort(num);
//         int len=num.length;
//         for(int i=0;i<len-2;i++){
//             if(i>0&&num[i]==num[i-1]){
//                 continue;
//             }
//             for(int j=i+1;j<len-1;j++){
//                 if(j>i+1&&num[j]==num[j-1]){
//                     continue;
//                 }
//                 int target=-(num[i]+num[j]);
//                 for(int k=j+1;k<len;k++){
//                     if(k>j+1&&num[k]==num[k-1]){
//                         continue;
//                     }
//                     if(num[k]==target){
//                         ArrayList<Integer> temp=new ArrayList<>();
//                         temp.add(num[i]);
//                         temp.add(num[j]);
//                         temp.add(num[k]);
//                         res.add(temp);
//                     }
//                 }
//             }
//         }
//         return res;
    }
    private void findTarget(int[] num,ArrayList<ArrayList<Integer>> res,int target,int left){
        int i=left+1,j=num.length-1;
        while(i<j){
            int sum=num[i]+num[j];
            if(sum>target){
                j--;
            }else if(sum<target){
                i++;
            }else{
                ArrayList<Integer> temp=new ArrayList<>();
                temp.add(num[left]);
                temp.add(num[i]);
                temp.add(num[j]);
                res.add(temp);
                i++;
                j--;
                while(i<j&&num[i]==num[i-1]){
                    i++;
                }
                while(i<j&&num[j]==num[j+1]){
                    j--;
                }
            }
        }
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 17:16
科大讯飞 算法工程师 28.0k*14.0, 百分之三十是绩效,惯例只发0.9
点赞 评论 收藏
分享
尊尼获获:闺蜜在哪?
点赞 评论 收藏
分享
我是小红是我:学校换成中南
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务