zoukankan      html  css  js  c++  java
  • [leetcode] 15. 三数之和

    此题相当恶心,多次超时

    暴力是O(N^3),明显不会过,不用考虑。

    比较好一点的思路是,a+b = -c,我们可以考虑用hash表存下来每个数字是否出现以及出现的次数,枚举a与b,然后看看此时-(a+b)是否存在。O(N^3),但是,仍然超时。

    至此我是想不到更优的思路了,于是开始搜别人的题解

    大部分人能过得思路是,首先将数组排序,然后枚举c,采用双指针法:i,j分别指向数组中第c+1个数,与最后一个数,
    if (num(i) + num(j)) < -c ,说明此时需要更大一点的数,则i++;
    if (num(i) + num(j)) > -c ,说明此时需要更小一点的数,则j++;
    if ((num(i) + num(j)) == -c,已经找到一个答案,注意当前c循环下可能还会有其它答案,应该继续寻找,而不是break去枚举下一个c,如下样例:

    输入:
    [-2,0,1,1,2]

    预期:
    [[-2,0,2],[-2,1,1]]

    按道理来说,此时应该能过了,可是还有一个1个测试用例超时 = =,可能c艹能过,java过不了吧

    其实可以处理一些剪枝,在符合条件的答案中,一个等式里同样的数字不会出现超过2次,0不会出现超过3次,
    所以我们可以把输入的nums处理一下,把出现3次以上的数字统统过滤。

    AC代码:

    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            Map<Integer, Integer> mp = new HashMap<>();
            List<List<Integer>> ans = new ArrayList<>();
    
            List<Integer> numList = new ArrayList<>();
    
            for (int num : nums) {
                if (mp.get(num) == null || mp.get(num) < 3) {
                    numList.add(num);
                    if (null != mp.putIfAbsent(num, 1))
                        mp.put(num, mp.get(num) + 1);
                }
            }
    
            numList.sort(Integer::compareTo);
    
            for (int k = 0; k < numList.size(); k++) {
                int i = k + 1, j = numList.size() - 1;
                int target = -(numList.get(k));
                while (i < j) {
                    if (i == k) {
                        i++;
                        continue;
                    } else if (j == k) {
                        j--;
                        continue;
                    }
                    int now = numList.get(i) + numList.get(j);
                    if (now == target) {
                        List<Integer> tmp = new ArrayList<>();
                        tmp.add(numList.get(i));
                        tmp.add(numList.get(j));
                        tmp.add(-target);
                        tmp.sort(Integer::compareTo);
                        ans.add(tmp);
                        if (numList.get(j - 1) == numList.get(j)) {
                            j--;
                        } else {
                            i++;
                        }
                    } else {
                        if (now > target) {
                            j--;
                        } else {
                            i++;
                        }
                    }
                }
            }
    
    
            return ans.stream().distinct().collect(Collectors.toList());
        }
    }
    
  • 相关阅读:
    CSS3 转换2D transform
    jquery中this和event.target的区别
    jQuery中事件对象e的事件冒泡用法示例(事件冒泡与阻止冒泡)
    表单Checkbox全选反选全不选
    表单获取焦点失去焦点
    表单非空校验
    无刷新评论
    定时器.倒计时
    虚拟硬件调整
    虚拟机功能
  • 原文地址:https://www.cnblogs.com/acbingo/p/9250227.html
Copyright © 2011-2022 走看看