Design Hash Table
Design and implement a TwoSum class. It should support the following operations: add and find. add - Add the number to an internal data structure. find - Find if there exists any pair of numbers which sum is equal to the value.
相似题目 | |
---|---|
简单 | Two Sum Two Sum IV - Input is a BST |
中等 | Unique Word Abbreviation |
双指针法
先给出双指针在有序列表中找到两数之和的算法。
- 初始化两个指针 low 和 high 分别指向列表的头尾。
- 从两个方向同时进行迭代,要么找到两数之和的解,要么两个指针相遇。
- 在每个步骤中,我们将根据不同的条件移动指针:
- 如果当前指针指向元素的和小于目标值,则应该增加总和来满足目标值,即将 low 指针向前移动获得更大的值。
- 如果当前指针指向元素的和大于目标值,则应该减少总和来满足目标值,即将 high 向 low 靠近来减少总和。
- 如果当前指针指向元素的和等于目标值,则直接返回结果。
- 如果两个指针相交,说明当前列表不存在组合成目标值的两个数
我们会发现, add(number)
函数将被频繁调用,而 find(value)
将不被那么频繁调用。
这样的使用模式下,意味着我们应该减少 add(number)
函数的时间消耗,因而我们是在 find(value)
对列表进行排序,而不是在 add(number)
。
class TwoSum {
private List<Integer> nums;
private boolean isSorted;
/** Initialize your data structure here. */
public TwoSum() {
this.nums = new ArrayList<>();
this.isSorted = false;
}
/** Add the number to an internal data structure.. */
public void add(int number) {
this.nums.add(number);
this.isSorted = false;
}
/** Find if there exists any pair of numbers which sum is equal to the value. */
public boolean find(int value) {
if (!this.isSorted) {
Collections.sort(this.nums);
}
int low = 0, high = this.nums.size() - 1;
while (low < high) {
int sum = this.nums.get(low) + this.nums.get(high);
if (sum == value) {
return true;
} else if (sum < value) {
low++;
} else {
high--;
}
}
return false;
}
}
/**
* Your TwoSum object will be instantiated and called as such:
* TwoSum obj = new TwoSum();
* obj.add(number);
* boolean param_2 = obj.find(value);
*/
哈希表法
和我自己的做法差不多,用哈希表实现快速查找和插入。只是 key 代表数字,value 代表出现次数。
class TwoSum {
HashMap<Integer, Integer> numCount;
/** Initialize your data structure here. */
public TwoSum() {
this.numCount = new HashMap<>();
}
/** Add the number to an internal data structure.. */
public void add(int number) {
if (numCount.containsKey(number)) {
numCount.replace(number, this.numCount.get(number) + 1);
} else {
numCount.put(number, 1);
}
}
/** Find if there exists any pair of numbers which sum is equal to the value. */
public boolean find(int value) {
for (Map.Entry<Integer,Integer> entry : this.numCount.entrySet()) {
int pair = value - entry.getKey();
if (pair == entry.getKey()) {
if (entry.getValue() > 1) {
return true;
}
} else {
if (this.numCount.containsKey(pair)) {
return true;
}
}
}
return false;
}
}
/**
* Your TwoSum object will be instantiated and called as such:
* TwoSum obj = new TwoSum();
* obj.add(number);
* boolean param_2 = obj.find(value);
*/
自己的解法
使用哈希表,key代表存储的数字,value代表该数字是否重复
class TwoSum {
// key代表存储的数字,value代表该数字是否重复
Map<Integer, Boolean> map;
/** Initialize your data structure here. */
public TwoSum() {
map = new HashMap<>();
}
/** Add the number to an internal data structure.. */
public void add(int number) {
if (!map.containsKey(number)) {
// 代表没有重复
map.put(number, false);
} else {
// 代表有重复
map.put(number, true);
}
}
/** Find if there exists any pair of numbers which sum is equal to the value. */
public boolean find(int value) {
for (Map.Entry<Integer, Boolean> entry : map.entrySet()) {
int key = entry.getKey();
int pair = value - key;
if (pair != key && map.containsKey(pair)) {
// 如果pair和key不相同,检查map中是否有pair
return true;
} else if (pair == key && map.get(key) == true){
// 如果pair和key相同且,检查key是否有重复值
return true;
}
}
return false;
}
}
/**
* Your TwoSum object will be instantiated and called as such:
* TwoSum obj = new TwoSum();
* obj.add(number);
* boolean param_2 = obj.find(value);
*/