[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());
    }
}
posted @ 2018-07-01 15:11  ACBingo  阅读(195)  评论(0编辑  收藏  举报