高级农民
- 积分
- 4092
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2017-1-22
- 最后登录
- 1970-1-1
|
170. Two Sum III - Data structure design
Design a data structure that accepts a stream of integers and checks if it has a pair of integers that sum up to a particular value.
Implement the TwoSum class:
TwoSum() Initializes the TwoSum object, with an empty array initially.
void add(int number) Adds number to the data structure.
boolean find(int value) Returns true if there exists any pair of numbers whose sum is equal to value, otherwise, it returns false.
Example 1:
Input
["TwoSum", "add", "add", "add", "find", "find"]
[[], [1], [3], [5], [4], [7]]
Output
[null, null, null, null, true, false]
Explanation
TwoSum twoSum = new TwoSum();
twoSum.add(1); // [] --> [1]
twoSum.add(3); // [1] --> [1,3]
twoSum.add(5); // [1,3] --> [1,3,5]
twoSum.find(4); // 1 + 3 = 4, return true
twoSum.find(7); // No two integers sum up to 7, return false
Constraints:
-105 <= number <= 105
-231 <= value <= 231 - 1
At most 104 calls will be made to add and find.
虽然是简单题,但是还是很值得讨论的。
我的虽然想到了排序但是再find的时候,固定思维带入了 2 sum 来做。其实可以用 two pointer 来查找。- class TwoSum:
- def __init__(self):
- self.arr = []
- def add(self, number: int) -> None:
- if not self.arr:
- self.arr.append(number)
- else:
- ind = bisect.bisect_left(self.arr, number)
- self.arr.insert(ind, number)
- def find(self, value: int) -> bool:
- res = set()
- for n in self.arr:
- if value - n in res:
- return True
- else:
- res.add(n)
-
- return False
-
- # Your TwoSum object will be instantiated and called as such:
- # obj = TwoSum()
- # obj.add(number)
- # param_2 = obj.find(value)
复制代码 双指针- class TwoSum:
- def __init__(self):
- self.arr = []
- def add(self, number: int) -> None:
- if not self.arr:
- self.arr.append(number)
- else:
- ind = bisect.bisect_left(self.arr, number)
- self.arr.insert(ind, number)
- def find(self, value: int) -> bool:
- # 优化:利用有序性使用双指针,空间复杂度 O(1)
- left, right = 0, len(self.arr) - 1
- while left < right:
- current_sum = self.arr[left] + self.arr[right]
- if current_sum == value:
- return True
- elif current_sum < value:
- left += 1
- else:
- right -= 1
- return False
-
- # Your TwoSum object will be instantiated and called as such:
- # obj = TwoSum()
- # obj.add(number)
- # param_2 = obj.find(value)
复制代码 其实最优的解法是用 dict,这样写入可以极快,查找的时候可以直接看具体数字出现的次数如果target == num,否则就查找是不是存在 target。- from collections import defaultdict
- class TwoSum:
- def __init__(self):
- # 记录每个数字出现的次数
- self.num_counts = defaultdict(int)
- def add(self, number: int) -> None:
- # 核心:写入的时间复杂度降为 O(1)
- self.num_counts[number] += 1
- def find(self, value: int) -> bool:
- # 遍历哈希表中的 key
- for num in self.num_counts:
- target = value - num
-
- # 坑点:如果 target 和 num 是同一个数,必须保证它出现至少 2 次
- if target == num:
- if self.num_counts[num] > 1:
- return True
- # 如果不是同一个数,只要 target 在字典里即可
- elif target in self.num_counts:
- return True
-
- return False
- # Your TwoSum object will be instantiated and called as such:
- # obj = TwoSum()
- # obj.add(number)
- # param_2 = obj.find(value)
复制代码 可以清晰看到时间复杂度的变化。
|
|