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)

  1. class TwoSum {
  2. private List<Integer> nums;
  3. private boolean isSorted;
  4. /** Initialize your data structure here. */
  5. public TwoSum() {
  6. this.nums = new ArrayList<>();
  7. this.isSorted = false;
  8. }
  9. /** Add the number to an internal data structure.. */
  10. public void add(int number) {
  11. this.nums.add(number);
  12. this.isSorted = false;
  13. }
  14. /** Find if there exists any pair of numbers which sum is equal to the value. */
  15. public boolean find(int value) {
  16. if (!this.isSorted) {
  17. Collections.sort(this.nums);
  18. }
  19. int low = 0, high = this.nums.size() - 1;
  20. while (low < high) {
  21. int sum = this.nums.get(low) + this.nums.get(high);
  22. if (sum == value) {
  23. return true;
  24. } else if (sum < value) {
  25. low++;
  26. } else {
  27. high--;
  28. }
  29. }
  30. return false;
  31. }
  32. }
  33. /**
  34. * Your TwoSum object will be instantiated and called as such:
  35. * TwoSum obj = new TwoSum();
  36. * obj.add(number);
  37. * boolean param_2 = obj.find(value);
  38. */

哈希表法

和我自己的做法差不多,用哈希表实现快速查找和插入。只是 key 代表数字,value 代表出现次数。

  1. class TwoSum {
  2. HashMap<Integer, Integer> numCount;
  3. /** Initialize your data structure here. */
  4. public TwoSum() {
  5. this.numCount = new HashMap<>();
  6. }
  7. /** Add the number to an internal data structure.. */
  8. public void add(int number) {
  9. if (numCount.containsKey(number)) {
  10. numCount.replace(number, this.numCount.get(number) + 1);
  11. } else {
  12. numCount.put(number, 1);
  13. }
  14. }
  15. /** Find if there exists any pair of numbers which sum is equal to the value. */
  16. public boolean find(int value) {
  17. for (Map.Entry<Integer,Integer> entry : this.numCount.entrySet()) {
  18. int pair = value - entry.getKey();
  19. if (pair == entry.getKey()) {
  20. if (entry.getValue() > 1) {
  21. return true;
  22. }
  23. } else {
  24. if (this.numCount.containsKey(pair)) {
  25. return true;
  26. }
  27. }
  28. }
  29. return false;
  30. }
  31. }
  32. /**
  33. * Your TwoSum object will be instantiated and called as such:
  34. * TwoSum obj = new TwoSum();
  35. * obj.add(number);
  36. * boolean param_2 = obj.find(value);
  37. */

自己的解法

使用哈希表,key代表存储的数字,value代表该数字是否重复

  1. class TwoSum {
  2. // key代表存储的数字,value代表该数字是否重复
  3. Map<Integer, Boolean> map;
  4. /** Initialize your data structure here. */
  5. public TwoSum() {
  6. map = new HashMap<>();
  7. }
  8. /** Add the number to an internal data structure.. */
  9. public void add(int number) {
  10. if (!map.containsKey(number)) {
  11. // 代表没有重复
  12. map.put(number, false);
  13. } else {
  14. // 代表有重复
  15. map.put(number, true);
  16. }
  17. }
  18. /** Find if there exists any pair of numbers which sum is equal to the value. */
  19. public boolean find(int value) {
  20. for (Map.Entry<Integer, Boolean> entry : map.entrySet()) {
  21. int key = entry.getKey();
  22. int pair = value - key;
  23. if (pair != key && map.containsKey(pair)) {
  24. // 如果pair和key不相同,检查map中是否有pair
  25. return true;
  26. } else if (pair == key && map.get(key) == true){
  27. // 如果pair和key相同且,检查key是否有重复值
  28. return true;
  29. }
  30. }
  31. return false;
  32. }
  33. }
  34. /**
  35. * Your TwoSum object will be instantiated and called as such:
  36. * TwoSum obj = new TwoSum();
  37. * obj.add(number);
  38. * boolean param_2 = obj.find(value);
  39. */