leetcode1. 两数之和

目录

1.暴力解法

2.hash表

描述:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。 

1.暴力解法

O(n^{2}),双指针遍历,直到找到两数之和等于target的,思路简单,但很及其低效。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target){
        for(int i=0;i<nums.size();i++){
            for(int j =i+1;j<nums.size();j++){
                if(nums[i]+nums[j]==target){
                    return {i,j};       //c++返回数组 return {a,b};
                }
            }
        }
    return {};                //返回函数返回types的对象,初始化为一个空的列表初始值设定项
    }
};

学习:(return 知识)

  1. 返回数组 return {a,b,..};      用大括号{},里面用,隔开
  2. return {}       返回函数要求类型的空值, 返回函数返回types的对象,初始化为一个空的列表初始值设定项
  3. return NULL;       返回值为NULL (C++中NULL与0等价),C++11的标准中加了一个用来表示空指针的常量值——nullptr;
  4. return ;   返回的是void,空值 
  • #ifdef              判断某个宏是否被定义,若已定义,执行随后的语句
  • #ifndef            与#ifdef相反,判断某个宏是否未被定义
  • __cplusplus     cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码 

#ifndef NULL                 //如果没有宏定义NULL的话
    #ifdef __cplusplus       // 如果定义了__cplusplus宏(定义了就说明这是C++代码)
        #define NULL 0       // NULL的值就是0
    #else
        #define NULL ((void *)0)         //不是C++代码,定义NULL可以为空指针(为了兼容C)
    #endif
#endif

暴力解法:执行用时: 488 ms,内存消耗: 9.6 MB

2.hash表

我们需要寻找两个数相加等于target,即对于一个给定的元素nums[i],在列表中找到另一个元素target-nums[i],找target-nums[i],用BF一一比较的话复杂度为O(n)

hashmap:但是如果用hashmap将数组所有值作为key(hash运算之后的值,比如modp运算...),数组下标为value,那么找我们找一个特定的值,只需要O(1)的复杂度。总的复杂度为O(n)

1.边赋值,边查找:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int,int> hashtable;        //建立一个空的hash表,key和value均为int型
    for(int i=0;i<nums.size();i++){         //遍历
        auto it=hashtable.find(target-nums[i]);   //每次在所有值中查找新值
        if(it!=hashtable.end()){        //找到,返回新值,及对应值的下标
            return {it->second,i};
        }
        hashtable[nums[i]]=i;           //没找到,就把新值加入hash表
    }
    return {};
    }
};

执行用时: 8 ms内存消耗: 10.6 MB

学习:(hashmap知识)

  1. hash表:就相当于原来你在数组中找一个相应的数,需要每个对比,但是现在我把值都标上号(hash函数),然后顺着标号一下就找到了,但是需要空间开销
  2. 创建一个unordered_map的对象hashtable,key和value均为int型。
  3. 因为我们要找一个值:target-nums[i],判断这个数组值是不是存在,所以就以数组值作为hashtable的key,数组索引做value,来寻找。
  4. auto:定义iterator值,避免了写类型(unordered_map<int,int>::iterator it=...)使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。编译器在编译期会将auto替换为变量实际的类型。
  5. hashtable.find():如果找到,返回iterator值(hashtable中的元素值),如果没找到,返回hashtable.end(),也就是空的
  6. it->second:返回当前iterator值的value值,此处即索引值,i返回索引值(it->first返回key值)。
  7. 赋值操作hashtable[nums[i]]=i; 对hashtable进行赋值,每次赋值并对已有的进行寻找,如果存在必然可以找到
  8. 其实可以先全部赋值,在一一寻找


1.哈希表的高速查找是空间换时间的典型应用,前期的建立时间随着数量级的增加而增加,后期的查找则永远是O(1)。如果面对海量数据,且需要大量搜索,那建议使用哈希表。而当面对小量数据(数量级由服务器决定)时,使用List更合适。

2.map与unordered_map:
map:key为有序排列,底层是红黑树,查找插入删除均为对数复杂度,。set同理。
unorderded_mapkey为无序排列,底层实现为hash table,理想情况查找复杂度为常数,消耗内存较多。unordered_set同理。

3.返回值类型是vector<int>,也是一个迭代器,数组值,根据代码可知,hashtable返回值需要加{},{}为空,返回一个数组,就直接在{}里面写多个值即可
2021-06-08

hashmap:查找时间复杂度O(1),yyds!就相当于找一本书,我把书的名字结果hash运算,给变成了一串对应的数字key——相当于编号了,然后找那本书直接找那个编号就行了,把值hash成了key,直接找索引就行了,其实也是一种简化思想。

将具象的东西给简化、抽象化,将其与一个个容易查找的东西对应起来(编号key值),然后理顺了就好找了

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值