我是如何刷 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++:

#include <vector>
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        if (nums.size() == 0 )
        {
            return nums;
        }
        vector<int> result;
        int temp = 0;
        int i=0,j=1; 
        for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++,i++) 
        {
            
    j = i + 1;
            for (vector<int>::iterator it2 = it + 1; it2 != nums.end(); it2++,j++) 
            {
                if ((*it + *it2) != target)
                {
                    continue;
                }
                else
                {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
             
        }
        return result;
    }
}

提交时间 提交结果 执行用时 内存消耗 语言
几秒前 通过 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 {};
}
};

 

posted @ 2020-05-17 20:58  wulongming88  阅读(276)  评论(0编辑  收藏  举报