[编程题] lc三数之和 (借助哈希表)

[编程题] lc:三数之和 (借助哈希表)

需求

image-20200726164004243

输出输出

image-20200726164019608

思考

如果用三个for遍历的话,会出现时间复杂度是O(n的3次方)

考虑使用两层for确定2个数,第三个数在哈希表中确定是否有。

  • 在确定第三个数的时候,需要判断这个数的下标是否是i指向的值,或者是j指向的值。如果是的话,这个数不少我们想要的。
  • 如果哈希表中的这个数不少i指向的也不是j指向的。此时,这个数与i j 构成的一组是我们需要的值。放入结果集合。
    • 如果我们选择直接把子结果放入List集合,发现最终有好多重复的。所以,我们采用对子结果先sort排序后,然后放入到Set集合去重。(排序是因为返回结果的子结果都是从小到大的规律;另外都img

Java代码:

import java.util.*;

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        /*思考:如果只用set的话,我们无法判断例如(-1,-1,2)这种数据在(-1,2)确定,
        另一个-1是否选取的问题(故使用Map记录下标)    //存入元素到map*/
        HashSet<ArrayList<Integer>> set = new HashSet<>();

        HashMap<Integer, Integer> map = new HashMap();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i);
        }

        //遍历确定2个,在哈希表查另一个
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (map.containsKey(-(nums[i] + nums[j])) &&
                        map.get(-(nums[i] + nums[j])) != i && map.get(-(nums[i] + nums[j])) != j) {
                    ArrayList<Integer> cur = new ArrayList<Integer>();
                    cur.add(nums[i]);
                    cur.add(nums[j]);
                    cur.add(0 - nums[i] - nums[j]);
                    Collections.sort(cur);
                    set.add(cur);
                }

            }
        }

        //把Set转为List
        List<List<Integer>> lis = new ArrayList<>();
        for(ArrayList<Integer> c:set){
            lis.add(c);
        }
        return lis;
    }
}

输出:

![image-20200726164050726]([编程题] 基础:如何使用大顶堆和小顶堆找topN.assets/image-20200726164050726.png)

猜你喜欢

转载自www.cnblogs.com/jiyongjia/p/13380874.html
今日推荐