小白跟随卡哥刷题第十天(hash表部分)

一、前言

今天终于是刷到了map这个数据结构,map对我来说总感觉有一点模糊的感觉,因为他的结构和以往的都不一样,是一对域。此后应该多刷刷关于set、map的题,也应该在刷题时去有意的使用这两个数据结构。言归正传开始今天的题目吧。

二、题目(力扣第1题—两数之和. - 力扣(LeetCode)

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

三、题解

先把卡哥的讲解放到这里(代码随想录)。这个题目并不是很难,如果常规一点的做法就是两重循环即可,这样比较简单但是就是时间复杂度比较大,这也是我看到这道题后第一时间想到的办法,后面看到了卡哥的讲解明白了,可以使用map当做hash表来解题,然后自己就试试了,也去搜索了很多自己不了解的知识点,然后很简单的解出来了这道题。接下来就把两重循环和map解法都说一下吧。

(1)两重循环
vector<int> twoSum(vector<int>& nums, int target) {
        int slow=0,fast;//定义类似于两个指针
        int len=nums.size();
        vector<int>vec;
        while(slow<len){
        	fast=slow+1;
        	while(fast<len){
        		if(nums[fast]+nums[slow]==target){
        			vec.push_back(slow);
        			vec.push_back(fast);
        			break;
				}
				else{
					fast++;
				}
			}
        	slow++;
		}
		return vec;
}

两重循环是比较简单的,请各位uu自行理解。

(2)map解法

先把代码弄上:

vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int>mp;//定义一个map
        for(int i=0;i<nums.size();i++){
        	auto it=mp.find(target-nums[i]);
        	if(it!=mp.end()){
        		return {it->second,i};
			}
			mp.insert(pair<int,int>(nums[i],i));
		}
        return{};
}

这里还涉及到迭代器的问题,我把这个讲解迭代器的b站视频链接放到这里http://【『教程』几分钟听懂迭代器】https://www.bilibili.com/video/BV18R4y1t7Hg?vd_source=ddc0c3418868b72b2e688c97e6f7a3eaicon-default.png?t=N7T8http://xn--https-8v3dhgl3100fo4gbnau4u3uin49b88llx9fgl2dpwsa//www.bilibili.com/video/BV18R4y1t7Hg?vd_source=ddc0c3418868b72b2e688c97e6f7a3ea,就我而言简单来说迭代器就是类似于数组的顺序,我们知道只有数组等少数数据结构是有位置信息的,而set、map等是没有下标的,它们有的是类似于顺序的迭代器来表示前后关系,这就是我理解的迭代器的作用。接下来重点讲讲代码。

这里的map有两个域,这里前面的一个代表数组中的下标位置,二第二个代表的则是数组中这个下标位置的值,这样组成了整个map,形成了这样的一个映射关系。

 map<int,int>mp;//定义一个map

这里使用auto是c++11的一个特色吧,用来寻找map中可以匹配成target的两个元素,it在这里指向的是一个迭代器,记住是迭代器。

auto it=mp.find(target-nums[i]);

这里it!=end()意思就是it指向的迭代器不等于尾迭代器(end是迭代器),就说明在前面的迭代器中找到了,就说明map中存在该值,输出这两个元素的下标,在map中就是第二个域,因此是it->sceond。

if(it!=mp.end()){
        		return {it->second,i};
			}

如果没有找到,就把这个数组中的元素的值和下标插入map中,从这里也可以看出来map第一、第二个域代表的含义,同时map的insert函数要与pair这个数据结构配合使用,请uu自己去查找相关内容,比较简单的小知识点。

mp.insert(pair<int,int>(nums[i],i));

至此整个代码就结束了,可以看出来map解法比二重循环的暴力解法不仅代码简洁而且时间复杂度要小的多(只有O(n))。因此也希望uu们可以有意识的使用set、map等数据结构来当做hash表(在合适的时候)来练习。

四、后记

遇到新的数据结构或者说容器,就要好好的理解和练习,今天遇到的map让我开始慢慢熟悉这些陌生的东西,也希望以后可以练的比较熟练。也提前祝各位uu端午节快乐!!!明日有事,会暂停刷题一天,请各位多多包涵。大家端午安康!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值