我是如何刷 LeetCode
参考知乎问题栏得到自己的理解:
确立目标:
(1)代码能力:更容易写出干净优雅,性能好的代码;
(2)面试得心应手;
[刷题的过程其实就是学习数据结构和算法的过程,挺不错的别人总结的资源 :给出思路和关键点,还横向地对知识点进行整理,尽量做到一题多解,多题同解。 现在GitHub仓库有30k的 ,并且Github上Leetcode排名第一, 欢迎大家关注。仓库地址: <a href="https://link.zhihu.com/?target=https%3A//github.com/azl397985856/leetcode"。or https://github.com/azl397985856/leetcode]
第一天:数组题(20200517)
两数之和:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
N久没练的代码 如下:
c++:
提交时间 提交结果 执行用时 内存消耗 语言
几秒前 通过 1896 ms 7.2 MB Cpp
上面用了暴力法,时间复杂度O(n2),穷;
复杂度分析:
时间复杂度:O(n^2)
对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n)O(n) 的时间。因此时间复杂度为 O(n^2)
空间复杂度:O(1)
仔细看了一下题解,尼玛还可以用哈希表的方式来求和,长见识了。
思路
标签:哈希映射
这道题本身如果通过暴力遍历的话也是很容易解决的,时间复杂度在 O(n2)
由于哈希查找的时间复杂度为 O(1),所以可以利用哈希容器 map 降低时间复杂度
遍历数组 nums,i 为当前下标,每个值都判断map中是否存在 target-nums[i] 的 key 值
如果存在则找到了两个值,如果不存在则将当前的 (nums[i],i) 存入 map 中,继续遍历直到找到为止
如果最终都没有结果则抛出异常
时间复杂度:O(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.find(target-nums[i]) != m.end()) //m中存在对应的键值
return {m[target-nums[i]] , i}; //m[target-nums[i]]为已经加入map的元素的索引,所以小于本轮循环中的i,放在前面
m[nums[i]]=i; //向map中添加元素
}
return {};
}
};
优解:
ps:对于存在重复元素的情况,用一遍哈希和两遍哈希确实会得到不同的结果,但是都是符合题目要求的。 题目描述确实有点含糊,但是这个题目的本意是让我们练习哈希表,题目说到You may assume that each input would have exactly one solution,即您可以假设每个输入都只有一个解决方案。
两遍哈希
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
m[nums[i]] = i; //向map中添加元素
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i]) != m.end() && m[target-nums[i]] != i) //如果m中存在对应的键值,并且不为i
return {i , m[target-nums[i]]};
}
return {};
}
};
一遍哈希
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.find(target-nums[i]) != m.end()) //m中存在对应的键值
return {m[target-nums[i]] , i}; //m[target-nums[i]]为已经加入map的元素的索引,所以小于本轮循环中的i,放在前面
m[nums[i]]=i; //向map中添加元素
}
return {};
}
};
暴力解法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int len=nums.size();
for(int i=0;i<len-1;i++)
for(int j=i+1;j<len;j++)
{
if(nums[i]+nums[j] == target)
return {i,j};
}
return {};
}
};