前言
大四越发感觉到代码能力的不足,虽然现在处于申请美研的阶段暂时逃开了找工作的问题,但是之前找实习碰壁的阴影和愈发感觉的到的找工作压力让我有了每天学几道LeetCode的想法,从现在开始积累一些算法提升一下代码能力,也方便自己以后翻阅查找知识点。
Problem 1. Two Sum
题目描述
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
算法思想
最开始的想法自然是暴力枚举,但是显然,OJ并不会让你在时间限制上舒舒服服暴力枚举。此处,暴力枚举是个O(N2)的时间复杂度,一般来说,我们为了提高时间的复杂度,需要用空间来换,代码界中的妥协吧。如何我们要用线性的时间复杂度O(N)来解决问题,那么就是说只能遍历一个数字,那么另一个数字呢,我们可以事先将其存储起来,使用一个HashMap,来建立数字和其坐标位置之间的映射,HashMap是常数级的查找效率,这样,我们在遍历数组的时候,用目标数值target减去遍历到的数字,就是另一个需要的数字了,直接在HashMap中查找其是否存在即可,注意要判断查找到的数字不是第一个数字,比如target是8,遍历到了一个4,那么另外一个4不能是当前遍历到的这个4,整个实现步骤为:先遍历一遍数组,建立HashMap映射,然后再遍历一遍,开始查找,找到且不重复,则记录index。
学到的知识点
- unordered_map与STL
这篇博客 Link 介绍了STL——map/unordered_map
在C++11中有新出4个关联式容器:unordered_map/unordered_set/unordered_multimap/unordered_multiset。
这4个关联式容器与map/multimap/set/multiset功能基本类似,最主要就是底层结构不同,使用场景不容。
如果需要得到一个有序序列,使用红黑树系列的关联式容器,如果需要更高的查询效率,使用以哈希表为底层的关联式容器。 - vector
这篇博客Link主要介绍了C++ vector的基本用法。
注意的点
- 运算符优先级
if (m.count(t) && m[t] != i)
这句代码中,要注意&&的优先级低于 != 。
详细C++运算符优先级见此Link
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> ans;
for (int i = 0; i < nums.size(); ++i) {
m[nums[i]] = i;
}
for (int i = 0; i < nums.size(); ++i) {
int t = target - nums[i];
if (m.count(t) && m[t] != i) {
ans.push_back(i);
ans.push_back(m[t]);
break;
}
}
return ans;
}
};