leetcode 力扣刷题哈希表初尝试

news/2024/5/18 7:44:26 标签: leetcode, 散列表, 算法, stl, c++, 哈希表

哈希表 刷题初尝试

  • 哈希表基础知识
  • 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.niftyadmin.cn/n/4942072.html

相关文章

Hlang--用Python写个语法解析器

文章目录 前言选型针对人群目标技术实现本文目标效果实现字符指针错误类型语法解析交互前言 目的纯粹,基于Python做一个简单的新的简单的编程语言。一方面是开拓视野,另一方面是作为毕设的临时过渡方案(没错,先前提到的算法平台,没有把握快速开发完毕,即便我使用大量的脚…

c++--异常

1.什么是异常 对于C语言来说&#xff0c;处理错误的机制有&#xff1a; 1.终止程序&#xff1a;如assert&#xff0c;缺陷&#xff0c;如发生内存错误&#xff0c;除0之外发生程序终止&#xff0c;用户无法接受。 2.返回错误码&#xff1a;对于大型程序来说&#xff0c;需要…

Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索

Similarities&#xff1a;精准相似度计算与语义匹配搜索工具包&#xff0c;多维度实现多种算法&#xff0c;覆盖文本、图像等领域&#xff0c;支持文搜、图搜文、图搜图匹配搜索 Similarities 相似度计算、语义匹配搜索工具包&#xff0c;实现了多种相似度计算、匹配搜索算法&…

【学习笔记】[AGC064D] Red and Blue Chips

神一样的 Kidulthood 考场上就看出来了这道题其实不难&#xff0c;但是祂没时间写了&#x1f605; 假设最后从底部到顶部的位置序列为 { x i } \{x_i\} {xi​}&#xff0c;那么每一步的操作就是固定的 将结论拓展可以得到&#xff0c;如果 x i > x i 1 x_i>x_{i1} xi​…

BC119 小乐乐与字符串

描述 在庆祝祖国母亲70华诞之际&#xff0c;老师给小乐乐出了一个问题。大家都知道China的英文缩写是CHN&#xff0c;那么给你一个字符串s&#xff0c;你需要做的是统计s中子序列“CHN”的个数。子序列的定义&#xff1a;存在任意下标a < b < c&#xff0c;那么“s[a]s[b…

人工智能原理(4)

目录 一、确定性推理 1、推理方式 2、控制策略 二、推理的逻辑基础 1、永真和可满足性 2、等价性和永真蕴含 3、置换与合一 三、自然演绎推理 四、归结演绎推理 1、子句型 2、鲁滨逊归结原理 3、归结策略 一、确定性推理 推理&#xff1a;就是按照某种策略从已有事…

Python:LVGL与触摸屏的调试记录

在移远模块EC-600M上驱动电容触摸屏&#xff0c;触摸屏控制IC为FT6206。 一、接口 TP屏的管脚如下&#xff0c;有6PIN。使用I2C接口通讯 所以我们用模块的I2C1通道&#xff0c;模块的IO口电压也是1.8v 二、I2C从地址 FT6x06芯片相对于主机来说是一个I2C设备 因此需要一个I2C…

基于Python科研论文绘制学习 - task1

绘制原则 必要性&#xff08;避免图多字少&#xff09; 易读性&#xff08;完整准确的标题、标签&#xff09; 一致性&#xff08;配图需要和上下文一致&#xff09; 尝试运行代码的时候出现了很多bug&#xff0c;基本都是围绕Scienceplots库的&#xff0c;在更新pip、pandas…