【leetcode 力扣刷题】哈希表初尝试

news2024/11/14 18:38:52

哈希表 刷题初尝试

  • 哈希表基础知识
  • 242. 有效的字母异位词
  • 383. 赎金信
  • 49. 字母异位词分组
  • 438. 找到字符串中所有字母异位词

哈希表基础知识

哈希表是一种数据结构,也叫散列表。哈希表中存储的是键值对,即(key,value),根据key直接查找到对应value,也能快速查找key是否在哈希表中,时间复杂度是O(1)。理解:可以把数组看作是哈希表,把数组下标index看作是key,对应下标中存储的是value,通过key查找元素的时候,就像是通过下标index访问数组,直接定位array[index]。
哈希表查找元素时,将key通过哈希函数(hashfunction)后映射为索引,通过该索引找到对应存储的value。

242. 有效的字母异位词

242. 有效的字母异位词
题目描述:【其实我没懂为什么这道题会跟哈希表扯上关系】在这里插入图片描述
理解题意:重点是“什么是字母异位词?”——实际上就是两个单词(字符串)中的字母及其出现的次数都一样,但是出现的顺序不一样。
理解题意后,解题思路就很清晰了,分别遍历s和t,统计其中出现的各个字符及其次数,最后对比这些字符及次数是否完全相等。因为题目中提到都是小写字母,因此用一个长度为26(只有26个小写英文字母),初始化全为0的数组count来记录字符串中各字母出现的次数。在遍历s的时候,对count[s[i]-‘a’]++,表示s中出现的各个字母及其次数;在遍历t的时候,对count[t[i]-‘a’]- -,表示t中出现的各个字母,及能否抵消掉s中该字母出现的次数;【注意直接用s[i]-'a’表示26个字母数组的下标是一种常用操作】最后遍历count数组,如果全为0,表示s和t是字母异位词,如果count中存在不为0的元素,就表示t不完全包括s中需要的字母(或s中不完全包括t中需要的字母)。
代码如下(C++):

class Solution {
public:
    bool isAnagram(string s, string t) {
    	//如果两者长度不一样,肯定不是字母异位词
        if(s.size() != t.size())
            return false;
        //统计各字母出现的次数
        int count[26] = {0};
        //遍历s,统计其中出现的字母及其次数
        for(int i = 0; i < s.size(); i++){
            count[s[i] - 'a']++;
        }
        //遍历t
        for(int i = 0; i < t.size(); i++){
            count[t[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++){
        	//如果有不为0的元素,表示在该字母上,s和t出现的次数不一样
            if(count[i] != 0) 
                return false;
        }
        return true;
    }
};

383. 赎金信

383. 赎金信
题目内容:在这里插入图片描述
ransomNote和magazine都由英文小写字母组成。理解题意,实际和上一题,字母异位词差不多,只是在字母异位词中,两个字符串中出现的字母及其次数必须完全一样,在这道题中,用magazine来组成ransomNote【提到magazine中每个字符只能在ransomNote中用一次,是比如ransomNote中有2个a,那么magazine中至少得有2个a才能满足要求】,实际上是要求ransomNote中需要的字母在magazine中都存在,并且magazine中这些字母的次数>ransomNote中出现的次数
实现过程同样是用count[26]数组来记录出现字母及其次数。先遍历ransomNote,对count[ransomNote[i]-‘a’]- -,表示ransomNote对该字母的需求量;再遍历magazine,对count[magazine[i]-‘a’]++,表示magazine对该字母的提供量;最后如果count中存在<0的元素,说明ransomNote中该字母的需求,magazine不能满足,不能满足题意,返回false。【相反>=0,都是能够满足的】
代码实现(C++):

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
    	//如果magazine中总的字符数小于ransomNote,直接返回false
        if(magazine.size() < ransomNote.size())
            return false;
        int count[26] = {0};
        //统计ransomNote中各字母的需求量
        for(int i = 0; i < ransomNote.size(); i++){
            count[ransomNote[i]-'a']--;
        }
        //统计magazine中各字母的提供量
        for(int i = 0; i < magazine.size(); i++){
            count[magazine[i]-'a']++;
        }
        for(int i = 0; i < 26; i++){
        	//如果有<0的说明magazine中该字母的提供量不能满足ransomNote中的需求量
            if(count[i] < 0)
                return false;
        }
        return true;
    }
};

49. 字母异位词分组

49. 字母异位词分组
题目内容:在这里插入图片描述
题目的关键点:①如何判断是字母异位词?方法Ⅰ. 字母异位词中出现的字母及其次数完全相同;方法Ⅱ. 字母异位词将字符串按照字母升序排序后是一样的;②如何对字母异位词分组?方法:哈希表,一组字母异位词key相同,字符串存到value中(很多个字符串怎么存,value用数组,比如vector); ③如何构造哈希表? 按照问题①的解决方案(两种对应最终的两种办法),将字符串变成键key,如果是字母异位词那么key是一样的,存到对应的value数组中,即可实现分组。
本题以及哈希表相关题目最最最关键的是,找到是要对什么构造哈希表,什么是key,什么是value。
两种代码分别如下(C++):

class Solution {
public:
	//方法Ⅰ,把字符串按照字母升序排序得到键key,构造哈希表
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> ans_map; //注意key对应的value是字母异位词构成的vector
        vector<vector<string>> ans;
        //遍历每一个字符串
        for(string& str_i : strs){
            string key = str_i;
            //使用字符串排序后的结果作为key
            sort(key.begin(), key.end());
            //将字符串加入到对应的key的value vactor中
            ans_map[key].emplace_back(str_i);
        }
        //取哈希表每个key对应的value(字母异位词分组)
        for(auto& ans_i : ans_map){
            ans.emplace_back(ans_i.second);
        }
        return ans;
    }
};

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> ans_map;
        vector<vector<string>> ans;
        //方法Ⅱ,把字符串中各个字母出现的次数构成key【比如aabccc,key是"213000……000"】
        for(string& str_i : strs){
            string key = string(26, '0');
            for(auto char_i : str_i)
                key[char_i-'a']++;
            //将字符串加入到对应的key的value vector中
            ans_map[key].emplace_back(str_i);
        }
        for(auto& ans_i : ans_map){
            ans.emplace_back(ans_i.second);
        }
        return ans;
    }
};

438. 找到字符串中所有字母异位词

438. 找到字符串中所有字母异位词
题目内容:【我不知道为什么一定要扯上滑动窗口,这道题不就是遍历s中所有和p长度一样的子串并判断嘛???】
在这里插入图片描述
理解题意,同样是判断字母异位词;遍历s中所有长度为p.len的子串,然后判断是不是p的字母异位词。怎么遍历子串呢?有一个start一个end,start=0,然后依次移动,end也是;子串移动的过程中,子串的字母及次数数组,对start的- -,对end的++。
代码如下(C++):

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        int s_len = s.size(), p_len = p.size();
        //如果s比p短,直接返回空结果
        if(s_len < p_len) return ans; 
        //统计子串和p中字母及其次数        
        vector<int> subCount(26,0), pCount(26,0);
        for(int i = 0; i < p_len; i++){
            subCount[s[i]-'a']++;
            pCount[p[i]-'a']++;
        }
        //对于第一个子串,先判断
        if(pCount == subCount)   ans.emplace_back(0);
        for(int start = 0; start < s_len - p_len; start++ ){
        	//移动到下一个子串            
            subCount[s[start] - 'a']--; //start对应字母次数--
            subCount[s[start + p_len] - 'a']++;  //end对应字母次数++(没有用额外的变量end表示,直接用start+p_len
			//判断新子串和p是否是字母异位词
            if(subCount == pCount){
                ans.emplace_back(start + 1);
            }         
        }
        return ans;
    }
};

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

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

相关文章

7-1 选择法排序

分数 20 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 本题要求将给定的n个整数从大到小排序后输出。 输入格式&#xff1a; 输入第一行给出一个不超过10的正整数n。第二行给出n个整数&#xff0c;其间以空格分隔。 输出格式&#xff1a; 在一行中输出从大到小有序…

openai多模态大模型:clip详解及使用

引言 CLIP全称Constrastive Language-Image Pre-training&#xff0c;是OpenAI推出的采用对比学习的文本-图像预训练模型。CLIP惊艳之处在于架构非常简洁且效果好到难以置信&#xff0c;在zero-shot文本-图像检索&#xff0c;zero-shot图像分类&#xff0c;文本→图像生成任务…

JAVA基础知识(五)——面向对象(中)

面向对象&#xff08;中&#xff09; 一、面向对象特征之一&#xff1a;封装与隐藏1.1 简介1.2 封装性的体现1.3 四种访问权限修饰符 二、类的成员之三&#xff1a;构造器2.1 构造器的特征2.2 构造器的作用2.3 语法格式2.4 构造器分类2.5 构造器重载2.6 属性赋值过程 三、扩展知…

Python的六种参数?

很多人说&#xff0c;Python的参数类型有四种、五种&#xff0c;我个人认为归纳起来是六种参数&#xff0c;分别为&#xff1a;位置参数&#xff08;Positional Arguments&#xff09;、默认参数&#xff08;Default Arguments&#xff09;、关键字参数&#xff08;Keyword Arg…

[C++11]

文章目录 1. 自动类型推导1.1 auto1.1.1 推导规则1.1.2 auto的限制1.1.3 auto的应用1.1.4 范围for 1.2 decltype1.2.1 推导规则1.2.2 decltype的应用 1.3 返回类型后置 2.可调用对象包装器、绑定器2.1 可调用对象包装器2.1.1 基本用法2.1.2 作为回调函数使用 2.2 绑定器 3. usi…

系统架构设计专业技能 · 信息系统基础

系列文章目录 系统架构设计专业技能 网络技术&#xff08;三&#xff09; 系统架构设计专业技能 系统安全分析与设计&#xff08;四&#xff09;【系统架构设计师】 系统架构设计高级技能 软件架构设计&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 …

vue 关闭prettier警告warn

这个就是我们创建vue cli的时候 把这个给默认上了 关闭这个只需在.eslintrc.js页面里边添加一行代码"prettier/prettier": "off"

Mac OS 中JDK 环境(jdk 1.8.0_831)安装配置、环境变量配置及卸载操作

前言&#xff1a; 摊牌了&#xff0c;本来就有点喜新厌旧的我&#xff0c;特意把系统和开发环境都拉到比较高&#xff0c;想试验一下兼容性和某些新特性&#xff0c;探索了一下新大陆&#xff0c;也见识了各种光怪陆离的妖魔鬼怪。 因为要着手云平台项目的重构改版和新系统的架…

5G技术与其对智能城市、物联网和虚拟现实领域的影响

随着第五代移动通信技术&#xff08;5G&#xff09;的到来&#xff0c;我们即将迈向一个全新的数字化世界。5G技术的引入将带来更高的速度、更低的延迟和更大的连接性&#xff0c;推动了智能城市、物联网和虚拟现实等领域的发展。 首先&#xff0c;5G技术将带来超越以往的网络速…

global 可不能随便用啊!寻找1-10000内的 Spyder 数遇到的小问题,却是大思考

今天遇到这样一个问题&#xff1a;寻找1-10000内的 Spyder 数&#xff0c;Spyder 数是指&#xff0c;如果将一个数的每个位上的数字相乘&#xff0c;再将这些乘积相加&#xff0c;最终得到的和等于原始数&#xff0c;那么该数就是 Spyder 数。 逻辑分析 这个逻辑其实很简单&…

软考A计划-系统集成项目管理工程师-法律法规-上

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

vulnhub靶机DarkHole_2

靶机下载地址&#xff1a;DarkHole: 2 ~ VulnHub 靶机发现 arp-scan -l 扫描端口 nmap --min-rate 10000 -p- 192.168.21.145 扫描服务 nmap -sV -sT -O -p22,80 192.168.21.145 漏洞扫描 nmap --scriptvuln -p22,80 192.168.21.145 这里有git源码泄露 git clone mirrors…

浅析DIX与DIF(T10 PI)

文章目录 概述DIF与DIX端到端数据保护 DIFDIF保护类型 SCSI设备支持DIFStandard INQUIRY DataExtended INQUIRY Data VPD pageSPT字段GRD_CHK、APP_CHK、REF_CHK字段 READ CAPACITY(16)响应信息 SCSI命令请求读命令请求写命令请求 DIF盘格式化相关参考 概述 DIF与DIX DIF&…

RK3588平台开发系列讲解(AI 篇)RKNN-Toolkit2 API 介绍

文章目录 一、RKNN 初始化及对象释放二、RKNN 模型配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解 RKNN-Toolkit2 API 详细说明。 一、RKNN 初始化及对象释放 在使用 RKNN Toolkit2 的所有 API 接口时,都需要先调用 RKNN()方法初始化 RKNN 对象,…

C++进阶 特殊类的设计

本篇博客介绍&#xff1a;介绍几种特殊的类 特殊类的设计 设计一个类不能被拷贝设计一个类 只能在堆上创建对象设计一个类 只能在栈上创造对象设计一个类不能被继承单例模式饿汉模式懒汉模式单例模式对象的释放问题 总结 设计一个类不能被拷贝 我们的拷贝只会发生在两个场景当…

【3D激光SLAM】LOAM源代码解析--scanRegistration.cpp

系列文章目录 【3D激光SLAM】LOAM源代码解析–scanRegistration.cpp 写在前面 本系列文章将对LOAM源代码进行讲解&#xff0c;在讲解过程中&#xff0c;涉及到论文中提到的部分&#xff0c;会结合论文以及我自己的理解进行解读&#xff0c;尤其是对于其中坐标变换的部分&…

chatGPT-对话爱因斯坦

引言 阿尔伯特爱因斯坦&#xff08; 1879年 3 月 14 日 – 1955 年 4 月 18 日&#xff09;是一位出生于德国的理论物理学家&#xff0c;被广泛认为成为有史以来最伟大、最有影响力的科学家之一。他以发展相对论而闻名&#xff0c;他还对量子力学做出了重要贡献&#xff0c;因…

安装搭建私有仓库Harbor

目录 一、安装docker编排工具docker compose 二、安装Harbor软件包 三、修改配置文件 四、运行安装脚本 五、安装后验证 六、使用Harbor 一、安装docker编排工具docker compose 在github上选择自己想要的版本下载 https://github.com/docker/compose/releases 下载好…

Android AppCompatActivity标题栏操作

使用 AndroidStudio 新建的工程默认用 AppCompatActivity &#xff0c;是带标题栏的。 记录下 修改标题栏名称 和 隐藏标题栏 的方法。 修改标题栏名称 Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R…

语言基础2 矩阵和数组

语言基础2 矩阵和数组 矩阵和数组是matlab中信息和数据的基本表示形式 可以创建常用的数组和网格 合并现有的数组 操作数组的形状和内容 以及使用索引访问数组元素 用到的函数列表如下 一 创建 串联和扩展矩阵 矩阵时按行和列排列的数据元素的二维数据元素的二维矩…