博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3数之和 3Sum
阅读量:6041 次
发布时间:2019-06-20

本文共 2249 字,大约阅读时间需要 7 分钟。

hot3.png

问题:

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.

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]]

解决:

① 首先想到暴力破解,O(n^3)的时间复杂度,必然超时。

② 数组排序+双指针 O(n^2) --- 动态规划

第一步,对数组排序。

第二步,
分析1:对于元素 S[i] , 最后的答案可以分为两种,包含 S[i] 的,和不包含 S[i] 的。当包含 S[i] 的情况都找到后,后续就可以不用再考虑 S[i] 。
分析2:对于 S[i] , l = i+1, r = len-1 。若 s[i] + S[l] + S[r] == 0, 则为原问题的一个解。
当 S[i] + S[l] > -S[r] 时,则 r--
当 S[i] + S[l] < -S[r] 时,则 l++
当 S[i] + S[i] = -S[r] 时, 表示是原问题的一个解,则 l++, r--;
第三步,性能优化。同样根据分析1,若 S[i] == S[i+1],可以跳过。

class Solution { //72ms

    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> threeSum(int[] nums) {
        if(nums == null || nums.length < 3) return res;
        Arrays.sort(nums);
        int len = nums.length;
        for (int i = 0;i < len - 2 ;i ++ ) {
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            twoSum(nums,i + 1,len - 1,nums[i]);
        }
        return res;
    }
    public void twoSum(int[] nums,int begin,int end,int sum1){
        while(begin < end){
            if(nums[begin] + nums[end] + sum1== 0){
                List<Integer> tmp = new ArrayList<>();
                tmp.add(sum1);
                tmp.add(nums[begin]);
                tmp.add(nums[end]);
                res.add(tmp);
                while(begin < end && nums[begin] == nums[begin + 1]) begin ++;
                while(begin < end && nums[end] == nums[end - 1]) end --;
                begin ++;
                end --;
            }else if(nums[begin] + nums[end] + sum1< 0){
                begin ++;
            }else{
                end --;
            }
        }
    }
}

② 这样写简单点

class Solution { //81ms

    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> threeSum(int[] nums) {
        if(nums == null || nums.length < 3) return res;
        Arrays.sort(nums);
        int len = nums.length;
        for (int i = 0;i < len - 2 ;i ++ ) {
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            twoSum(nums,i + 1,len - 1,nums[i]);
        }
        return res;
    }
    public void twoSum(int[] nums,int begin,int end,int sum1){
        while(begin < end){
            if(nums[begin] + nums[end] + sum1== 0){
                res.add(Arrays.asList(sum1,nums[begin],nums[end]));
                while(++ begin < end && nums[begin] == nums[begin - 1]);
                while(-- end > begin && nums[end] == nums[end + 1]);
            }else if(nums[begin] + nums[end] + sum1< 0){
                begin ++;
            }else{
                end --;
            }
        }
    }
}

转载于:https://my.oschina.net/liyurong/blog/1523800

你可能感兴趣的文章
Ubuntu 10.04升级git 到1.7.2或更高的可行方法
查看>>
Spring Security4实战与原理分析视频课程( 扩展+自定义)
查看>>
第一周博客作业
查看>>
thinkpython2
查看>>
oracle recyclebin与flashback drop
查看>>
svmlight使用说明
查看>>
Swing 和AWT之间的关系
查看>>
Mysql设置自增长主键的初始值
查看>>
Android计时器正确应用方式解析
查看>>
获取post传输参数
查看>>
ASP生成静态页面的方法
查看>>
HDU 1325 Is It A Tree? 判断是否为一棵树
查看>>
Shell命令-文件压缩解压缩之gzip、zip
查看>>
个人总结
查看>>
uva 673 Parentheses Balance
查看>>
Bzoj 2252: [2010Beijing wc]矩阵距离 广搜
查看>>
css 禁止选中文本
查看>>
bzoj2165
查看>>
算术运算表达式正则及分析
查看>>
Oracle 12c 多租户 手工创建 pdb 与 手工删除 pdb
查看>>