2019.1.8
这道题是LeetCode第一题,是说最经典的也不为过,当然也正式开启了我在LeetCode上的征程,不知道自己能坚持多久,只是希望自己能一直踏实的学习进步,保持对编程的热爱之情,戒骄戒躁,朝着目标不断前进!
初步计划:(没有特殊情况下)
Simple题,每天两题;Medium题,每天一题;Hard题,每天一题(不知道能不能坚持到hard...Orz)
不追求速度,争取把每道题都能吃透,将自己的解法与官方解答及相关博客,整理出相应的各种解法。好了,话不多说,开始吧。
题目描述:
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].
这道题给定一个整数数组 nums
和一个目标值 target
,在该数组中找出和为目标值的那两个整数,并返回他们的数组下标,并且题设已经声明了每种输入只会有一个答案。
解法一:
第一反应就是暴力求解(暴力也是一种美。。=-=),因为题设已经声明了每种输入只会有一个答案,所以可以利用双重循环遍历数组,将不同下标的两个数进行相加求和,与目标数进行比较,满足的就返回输出即可,当然也可以用目标数与外层循环元素的差值来比较,原理是一样的
下面是C++的代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n=nums.size();
vector<int> result;
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(nums[i]+nums[j]==target){
result.push_back(i);
result.push_back(j);
return result;
}
}
}
}
};
执行用时96ms
复杂度分析:
-
时间复杂度:O(n^2), 对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n) 的时间。因此时间复杂度为 O(n^2)。
-
空间复杂度:O(1)。
解法二:
官方解法:两遍哈希表
借助了以空间换时间的方法,使用一个HashMap,来建立数字和其坐标位置之间的映射,因为哈希表可以实现接近恒定的时间进行快速查找(有冲突时会退化为O(n)),所以使用两次迭代,在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i]target−nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i] 本身。
下面是C++代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> res;
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) {
res.push_back(i);
res.push_back(m[t]);
break;
}
}
return res;
}
};
执行用时12ms,效率杠杠的~
复杂度分析:
-
时间复杂度:O(n), 我们把包含有 nn 个元素的列表遍历两次。由于哈希表将查找时间缩短到 O(1) ,所以时间复杂度为 O(n)。
-
空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表中存储了 n 个元素。
解法三:
一次遍历哈希表
在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for (int i = 0; i < nums.size(); ++i) {
if (m.count(target - nums[i])) {
return {i, m[target - nums[i]]};
}
m[nums[i]] = i;
}
return {};
}
};
执行时间8ms,超级快!
复杂度分析:
-
时间复杂度:O(n), 我们只遍历了包含有 nn个元素的列表一次。在表中进行的每次查找只花费 O(1) 的时间。
-
空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 n个元素。