我正在努力研究LeetCode上的Two Sum III。这是一个问题:
设计并实现TwoSum类。它应该支持以下内容 操作:添加和查找。 add - 将数字添加到内部数据 结构体。查找 - 查找是否存在任何总和的数字对 等于该值。 例如,add(1);加(3);添加(5);
找到(4) - > true find(7) - >假
我知道两个可接受的解决方案,第一个使用List,第二个使用map。以下是我的两个解决方案:
列表实施:
public class TwoSum {
private List<Integer> list;
public TwoSum() {
list = new ArrayList<Integer> ();
}
public void add(int num) {
list.add(num);
}
public boolean find (int sum) {
if(list.size() == 1)
return list.get(0) == sum;
for (int i = 0; i < list.size(); i++) {
if (list.contains(sum - list.get(i))) {
if (list.indexOf(sum - list.get(i)) == i)
continue;
return true;
}
}
return false;
}
}
地图实施:
public class TwoSum2 {
private Map<Integer, Integer> map;
public TwoSum2() {
map = new HashMap<Integer, Integer>();
}
public void add(int num) {
if (!map.containsKey(num))
map.put(num, 1);
else
map.put(num, map.get(num) + 1);
}
public boolean find(int sum) {
if(map.size() == 1)
return map.containsKey(sum);
for (int num : map.keySet()) {
if (map.containsKey(sum - num)) {
if (num == sum - num && map.get(num) == 1)
continue;
return true;
}
}
return false;
}
}
两个解决方案应该给我相同的复杂度,O(1)表示添加,O(n)表示查找。但是,对于我的几个测试用例,List实现略快一些。我能想到的唯一原因是需要一些时间才能在地图中获取哈希码并找到密钥。但我不确定这个答案。可能是Map实现速度较慢的可能原因是什么?
感谢。
答案 0 :(得分:1)
对于HashMap,有一个称为加载因子的变量。如果达到加载因子,HashMap将重新分配更多内存并重新分配所有键值对。在这种情况下,单个put动作的复杂度为O(n),因此它可能更慢。看看这个documentation
HashMap的一个实例有两个影响其性能的参数: 初始容量和负载系数。容量是数量 哈希表中的桶,而初始容量就是 创建哈希表时的容量。负载系数是a 衡量哈希表在其之前可以获得多长的度量 容量自动增加。当中的条目数 哈希表超出了加载因子和当前的乘积 容量,哈希表重新哈希(即内部数据 重建结构),以便哈希表大约两次 桶的数量。
作为一般规则,默认加载因子(.75)提供了一个好处 时间和空间成本之间的权衡。值越高,值越低 空间开销,但增加了查找成本(反映在大多数 HashMap类的操作,包括get和put)。预期的 应该考虑地图中的条目数量及其加载因子 帐户设置其初始容量时,以便最小化 重新运算的次数。如果初始容量大于 条目的最大数量除以加载因子,没有重新哈希 操作将永远发生。