解题思路:
\qquad
对每个数nums[i]
,仅需在数组中搜索target-nums[i]
是否存在。
优化思路:
\qquad
首先能想到,利用哈希表O(1)
查询target-nums[i]
。
\qquad
建立map<int, vector<int>>
的表能够处理重复元素,保证找到所有解。但是,能否进一步优化?
\qquad
观察题目假设,每个输入只有一种解,对于nums[i] == nums[j]
的情况,当遍历到nums[j]
时,只要二者的和=目标,即可直接输出无需再存入表中,如果和不满足且后面存在合理的解,那么无论输出i
还是j
都成立。所以建立的表无需处理重复的情况,可建表map<int,int>
。
\qquad 到这里,思路已经足够简洁,但是能否进一步优化代码实现提高运行速度?
优化代码:
\qquad
1)使用unordered_map
。
map | unordered_map | |
---|---|---|
特点 | 有顺序(key升序) | 元素排列无顺序 |
实现方式 | 红黑树 | 哈希表(散列表) |
时间效率 | O(logn) | O(1) |
存储效率 | 接近100% | 表中存在未使用的值 |
稳定性分析 | 平衡二叉树,十分稳定O(logn) | 不稳定,最快O(1),最坏O(n)【冲突过多时】 |
头文件 | <map> | <unordered_map> |
\qquad 注:写题大多时候适用 unordered_map,当对查询稳定性要求高、需要排序时用map。
\qquad
2)虽然函数返回值为vector<int>
,但已知返回长度,可以不建立数组,直接返回{num1,num2}
。
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
int n = nums.size();
for(int i = 0; i < n; i++)
{
if(m.count(target - nums[i]) == 0)
{
m[nums[i]] = i;
}
else
{
return {i, m[target - nums[i]]};
}
}
return {};
}
参考博客:
https://blog.csdn.net/JCjunior/article/details/107471425
https://blog.csdn.net/qq_45890970/article/details/123955261