1 题目
题目:两数之和III-数据结构设计(Two Sum III - Data structure design)
描述:设计并实现一个 TwoSum 类。他需要支持以下操作:add 和 find。add -把这个数添加到内部的数据结构。find -是否存在任意一对数字之和等于这个值
lintcode题号——607,难度——easy
样例1:
add(1);add(3);add(5);
find(4)//返回true
find(7)//返回false
2 解决方案
2.1 思路
比较直观的方式,考虑内部维护一个排序数组,add操作向已排序的数组添加元素,查找位置耗时O(log n),插入数组耗时O(n),add操作的时间复杂度为O(n),find从已排序的数组找到两个和为目标值的数,可以使用对向双指针的方式,使用两个指针分别从头尾开始向中间走,若指针指向的两个值的和小于目标值,则左指针往右一步,若大于目标值,则右指针往左一步,find操作的时间复杂度为O(n)。
再考虑内部维护一个无序的容器,即维护一个哈希表,此时add操作的时间复杂度为O(1),find操作需要遍历所有元素,时间复杂度为O(n),该题使用无序容器更优于有序容器。
2.2 时间复杂度
使用哈希表方式,add操作时间复杂度为O(1),find操作时间复杂度O(n)。
2.3 空间复杂度
使用哈希表方式,需要用到unordered_map数据结构,空间复杂度为O(n)。
3 源码
细节:
- 使用哈希表法,维护一个无序的哈希表,因为可能出现相同的元素,哈希表保存的是元素值到元素出现次数的映射。
C++版本:
unordered_map<int, int> numsCount; // 哈希表保存元素以及出现的次数
/**
* @param number: An integer
* @return: nothing
*/
void add(int number) {
// write your code here
if (numsCount.find(number) != numsCount.end())
{
numsCount.at(number)++;
}
else
{
numsCount.insert({number, 1});
}
}
/**
* @param value: An integer
* @return: Find if there exists any pair of numbers which sum is equal to the value.
*/
bool find(int value) {
// write your code here
for (auto it : numsCount)
{
int temp = value - it.first;
if (numsCount.find(temp) == numsCount.end())
{
continue; // 跳过没有匹配成功的数
}
if (temp != it.first)
{
return true; // 两个匹配不相等,匹配成功
}
if (temp == it.first && numsCount.at(temp) > 1)
{
return true; // 两个匹配相等,需要序列中该值有两个或以上
}
}
return false;
}