哈希表练习题

前言

本次博客将要写一写,哈希表的一些使用

哈希表主要是一个映射,比如数组就是一个哈希表

是一个整型对应另一个整型,介绍的哈希表还是要以写题目为例

第一题

242. 有效的字母异位词 - 力扣(LeetCode)

直接来看这个题目吧

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词

提示:

  • 1 <= s.length, t.length <= 5 * 10的4次方
  • s 和 t 仅包含小写字母

思路

暴力思路

我们可以使用两个for循环一个一个判断,从第一个字符到最后一个字符与第二个字符串每一个元素比对,其次还要进行去重操作,因为在比对过程中可能会出现重复的字符

比如 aabcd abcdf这两个字符串如果一一比对第二个字符会被配对两次,而按照代码逻辑

会把他两当成配对成功,所以还需要一个状态数组,来进行去重,暴力思路也有细节的

看代码吧!

#include<iostream>
#include<string.h>
using namespace std;
int state[50010] = {0};
int main()
{//定义两个字符串char a[] = "bacdeffffassadawd";char b[] = "ssadawdbacdeffffa";int sizea = strlen(a);int sizeb = strlen(b);int flag = 0;//如果大小不等,直接排除if (sizea != sizeb){printf("不是\n");return 0;}  for (int i = 0; i < sizea; i++){for (int j = 0; j < sizeb; j++){flag = 0;if (a[i] == b[j]&&!state[j]){state[j] = 1;flag = 1;break;}}if (flag == 0) { printf("不是\n");break;}}if (flag == 1)printf("找到了\n");return 0;
}

再看看测试结果

改个数据

ok暴力可以解决问题

不够代价可不小

首先额外开了一个int类型大小为5万的数组,其次时间复杂度为o(n^2)

不太好的一个代码,但是思路是无罪的

哈希表思路

思路

题目中,只有26个字母唉而且只有小写字母

我们可以用0~25分别映射a~z这个字母,完全可以采用数组这个结构

第一个字符串中 字母出现一次,让对应的下标的数组的值加一

第二个字符串  字母出现一次,让对应的下标的数组的值减一

最后遍历一遍数组

如果有不等于0的值就判断为不是

如果全部通过,就判断为是

看代码吧

int main()
{//这里随便写的一个char a[] = "abcdefghijilmndjalwjdjakd";char b[] = "lmndjalwjdjakdabcdefghiji";//初始化为0(非完全初始化默认的元素就是为0)int arr[26] = {0};int asize = strlen(a);int bsize = strlen(b);//如果长度不一,一定不是if (asize != bsize){printf("不是\n");return 0;}for (int i = 0; i < asize; i++){arr[a[i] - 'a']++;arr[b[i] - 'a']--;}for (int i = 0; i < 26; i++){if (arr[i] != 0){printf("不是\n");return 0;}}printf("是\n");return 0;
}

OK,最终结果也不太想,演示了,没问题的

看下一题

第二题

349. 两个数组的交集 - 力扣(LeetCode)

给定两个数组 nums1 和 nums2 ,返回 它们的 

交集

输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

暴力思路

其实就是,通过两个for循环,依次遍历即可,相等的记录在另一个数组中

额,有点不想敲了 哈哈哈,来吧

注意 两个数组的大小都在1000以内,所以 结果数组大小 在1010就行

他们的值是在0~1000 其实short类型就够了,当然这里仍然需要我们自己去去重

毕竟他们的值实在0~1000,我们可以再来一个1000大小的数组来判断这个值出现了没有

如果他们的值很大很大暴力法是不可行的,好吧这里的状态数组本身就是一个哈希表

它的含义是state[i]   i为0~1000的范围 如果该值已经出现state[i]==1

没有出现就默认为0 这样大家就懂了吧

看代码喽

short result[1010];
short state[1000];
int main()
{short a[] = { 1,2,3,4,5,6,7,8,9,10};short b[] = { 2,2,3,4,5,5,6,6,6,6,6};size_t sizea = sizeof(a) / sizeof(a[0]);size_t sizeb = sizeof(b) / sizeof(b[0]);size_t sizer = 0;for (int i = 0; i < sizea; i++){for (int j = 0; j < sizeb; j++){if (a[i] == b[j]&&!state[a[i]]){result[sizer++] = a[i];state[a[i]] = 1;break;}}}for (int i = 0; i < sizer; i++){printf("%d ", result[i]);}return 0;
}

看结果

没有错,但是这个代码o(n)的空间

o(n^2)的时间实在不好,那么看优化的吧

这里用set

不过这里的set容器是c++代码

也好理解

最普通的set可以自动去重,而且会自动排序

不要觉得功能多,实际上时间复杂度也高

这里就简单介绍set就好,这里是STL库里的内容

思路就是,把数组中元素放到第一个set容器里面

然后,再构建一个set,如果可以在第一个set里找到与第二个数组相同的元素,就纪录在第二

个set中

ok,看代码

int main()
{set<int>st1;set<int>st2;short a[] = { 1,2,3,4,5,6,7,8,9,10};short b[] = { 2,2,3,4,5,5,6,6,6,6,6};size_t sizea = sizeof(a) / sizeof(a[0]);size_t sizeb = sizeof(b) / sizeof(b[0]);for (int i = 0; i < sizea; i++){st1.insert(a[i]);}for (int i = 0; i < sizeb; i++){//这里是一个迭代器if (st1.find(b[i]) != st1.end()){st2.insert(b[i]);}}//遍历一遍for (auto& ele : st2){cout << ele<<" ";}return 0;
}

第三题

202. 快乐数 - 力扣(LeetCode)

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入:n = 19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

示例 2:

输入:n = 2
输出:false

 提示:

  • 1 <= n <= 2^31-1

思路

首先看到这个题目先得分析数据

n的大小为2的31次方-1就是一个int类型的最大值

但是在计算过程中会不会越界呢?这个大小为20亿左右

是一个十位数那么假设每一位都是9

9^2*10也才810所以int类型可以

其次再看题意

他是要出现一个1才为快乐数呀,这个很好判断对吧

那么怎么判断它不是快乐数,也就是它一直循环

既然是循环,那么肯定是一个圈就是在运算的过程中,会转一圈从而出现之前出现过的数

对吧这个时候,哈希表的判断是否存在于一个集合中就起作用了

set

它的增删查改时间复杂度为logn

如果使用暴力的话,它的时间复杂为n,算了这里不写暴力了

看代码吧

应该也挺好懂的

bool isHappy(int n) {set<int>st;int sum = 0;int c = n;st.insert(n);while (1){sum = 0;while (c){sum += pow(c % 10, 2);c /= 10;}c = sum;if (c == 1)return true;for (auto& ele : st){if (ele == c)return false;}st.insert(c);}
}int main(){if (isHappy(50))printf("yes");elseprintf("no");return 0;}

总结

今天就写这三题,OK,祝大家开心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chrome插件 脚本 使用和推荐

chrome插件使用 在极简插件中可以进行下载并进行安装, 内部有安装教程在极简插件中搜索"油猴",下载一个油猴插件,并安装,可以用于下载很多的用户脚本用户脚本下载地址Greasy Fork,里面有很多实用的用户脚本供下载,并在油猴中进行管理 推荐的插件 Tampermonkey 篡改…

小红书自动互动,建立个人品牌的秘密武器!

在数字化的今天&#xff0c;个人品牌的重要性不言而喻。它不仅能让你在人群中脱颖而出&#xff0c;还能为你的事业或生意带来无尽的机会。然而&#xff0c;建立并推广个人品牌并非易事&#xff0c;需要策略、耐心和一定的工具辅助。在这里&#xff0c;我们要探讨的是如何利用小…

常用路由交换协议

常用路由交换协议 协议汇总优秀博客参考资料 协议汇总 路由协议原理优点缺点使用场景华为配置示例静态路由网络管理员手动配置路由信息配置简单&#xff0c;安全性高不适应网络变化&#xff0c;管理复杂小型网络或不常变化的环境system-viewip route-static 目的网段 掩码 下一…

【Python数据库】Redis

文章目录 [toc]数据插入数据查询数据更新数据删除查询存在的所有key 个人主页&#xff1a;丷从心 系列专栏&#xff1a;Python数据库 学习指南&#xff1a;Python学习指南 数据插入 from redis import Redisdef insert_data():redis_cli Redis(hostlocalhost, port6379, db…

智慧健康旅居养老产业,做智慧旅居养老服务的公司

随着社会的进步和科技的飞速发展&#xff0c;传统的养老模式已经无法满足 现代老年人的多元化 需求。智慧健康旅居养老产业应运而生&#xff0c;成为了一种新型的养老模式&#xff0c;旨在为老年人提供更加舒适、便捷、安全的养老生活。随着社会的进步和人口老龄化趋势的加剧&a…

MATLAB初学者入门(15)—— 随机森林

随机森林是一种强大的机器学习方法&#xff0c;基于多个决策树的训练结果进行集成学习&#xff0c;以提高整体的预测准确性和稳定性。这种方法不仅适用于分类问题&#xff0c;也非常适合于回归问题。MATLAB中的Statistics and Machine Learning Toolbox提供了易于使用的随机森林…

vue2 upload多图片上传

dom <el-upload:class"{ uoloadSty: showBtnImg, disUoloadSty: noneBtnImg }"class"avatar-uploader"ref"upload" action"#":limit"limitCountImg" //限制上传图片的数量:show-file-list"true" //列表展示:au…

如何3分钟,快速开发一个新功能

背景 关于为什么做这个代码生成器&#xff0c;其实主要有两点: 参与的项目中有很多分析报表需要展示给业务部门&#xff0c;公司使用的商用产品&#xff0c;或多或少有些问题&#xff0c;这部分可能是历史选型导致的&#xff0c;这里撇开不不谈&#xff1b;项目里面也有很多C…

Sping源码(七)—context: component-scan标签如何扫描、加载Bean

序言 简单回顾一下。上一篇文章介绍了从xml文件context component-scan标签的加载流程到ConfigurationClassPostProcessor的创建流程。 本篇会深入了解context component-scan标签底层做了些什么。 component-scan 早期使用Spring进行开发时&#xff0c;很多时候都是注解 标…

机器人定位导读

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、机器人中常见的定位技术介绍二、gnss、rtk定位原理三、【依赖二维激光雷达与全局地图的定位算法】amcl&#xff08;蒙特卡…

项目上线流程(保姆级教学)

01&#xff1a;注册阿里云账户 02&#xff1a;登录阿里云 03&#xff1a;在桌面新建记事本保存个人账号密码等信息 04&#xff1a;完成重置密码 05&#xff1a;安装宝塔面板 命令行 yum install -y wget && wget -O install.sh http://download.bt.cn/install/instal…

大学生在线考试|基于SprinBoot+vue的在线试题库系统系统(源码+数据库+文档)

大学生在线考试目录 基于SprinBootvue的在线试题库系统系统 一、前言 二、系统设计 三、系统功能设计 试卷管理 试题管理 考试管理 错题本 考试记录 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#…

华纳云:怎么防止租用服务器的数据丢失?

要防止租用服务器上的数据丢失&#xff0c;可以采取以下一些措施&#xff1a; 定期备份数据&#xff1a;建立定期备份数据的机制&#xff0c;将重要数据备份到安全的地方&#xff0c;例如云存储服务、外部硬盘或者另一个服务器上。备份频率可以根据数据的重要性和变动频率来确定…

Java数据结构堆

堆的概念 所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中。 小根堆&#xff1a;根节点的大小小于孩子节点。整棵树都是小根堆必须满足每颗子树都是小根堆。 堆的存储方式 从堆的概念可知&#xff0c;堆是一棵完全二叉树&#xff0c;因此可以层序的规则采用顺序的…

java算法题42501

题目 算法题: (1)给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 输入:nums = [1,2,3,1] 输出:true解法1,使用HashSet 使用HashSet来存储数组中的元素,同时遍历数组。如果遍历过程中发现某个元素…

【JVM】java内存区域

目录 一、运行时数据区域 1、方法区 2、堆 3、虚拟机栈 4、本地方法栈 5、程序计数器 6、运行时常量池 二、HotSpot虚拟机的对象 1、对象的创建 指针碰撞&#xff1a; 空闲列表&#xff1a; 2、对象的内存布局 对象头 实例数据 对齐填充 3、对象的访问定位 句…

git忽略文件配置 !

.gitignore中!表示取反 注意&#xff0c;如果父目录被排除&#xff0c;则父目录下的子目录也会被排除&#xff0c;此时对父目录下的子目录取反也不会生效&#xff0c;比如存在目录结构&#xff0c;再.gitignore目录下配置的 /*&#xff08;排除所有文件&#xff09;&#xff0c…

【LLM多模态】Qwen-VL模型结构和训练流程

note 观点&#xff1a;现有很多多模态大模型是基于预训练&#xff08;和SFT对齐&#xff09;的语言模型&#xff0c;将视觉特征token化并对齐到语言空间中&#xff0c;利用语言模型得到多模态LLM的输出。如何设计更好的图像tokenizer以及定位语言模型在多模态LLM中的作用很重要…

面试算法题之暴力求解

这里写目录标题 1 回溯1.1 思路及模板1.1 plus 排列组合子集问题1.2 例题1.2.1 全排列1.2.2 N 皇后1.2.3 N皇后问题 II1.2.4 子集 &#xff08;子集/排列问题&#xff09;1.2.4 组合(组合/子集问题)1.2.5 全排列 &#xff08;排列问题&#xff09;1.2.1做过1.2.6 子集II &#…

项目十一:爬取热搜榜(小白实战级)

首先&#xff0c;恭喜各位也恭喜自已学习爬虫基础到达圆满级&#xff0c;今后的自已python爬虫之旅会随着网络发展而不断进步。回想起来&#xff0c;我学过请求库requests模块、解析库re模块、lmxl模块到数据保存的基本应用方法&#xff0c;这一次的学习python爬虫之旅收获很多…