[编程题] lc:三数之和 (借助哈希表)
需求
输出输出
思考
如果用三个for遍历的话,会出现时间复杂度是O(n的3次方)
考虑使用两层for确定2个数,第三个数在哈希表中确定是否有。
- 在确定第三个数的时候,需要判断这个数的下标是否是i指向的值,或者是j指向的值。如果是的话,这个数不少我们想要的。
- 如果哈希表中的这个数不少i指向的也不是j指向的。此时,这个数与i j 构成的一组是我们需要的值。放入结果集合。
- 如果我们选择直接把子结果放入List集合,发现最终有好多重复的。所以,我们采用对子结果先sort排序后,然后放入到Set集合去重。(排序是因为返回结果的子结果都是从小到大的规律;另外都
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)