leetcode 经典哈希表与字符串题目(思路、方法、code)

PFC中pb模型实战:从胶结参数设置到破坏模拟全流程解析 本文详细解析了PFC软件中平行胶结模型(PB模型)的实战应用全流程。从胶结参数(pb_kn, pb_ks, pb_ten等)的物理意义精准赋值入手,深入探讨了模型构建、胶结施加以避免初始损伤的技巧,并系统介绍了破坏过程的监测、阈值判定方法以及高级可视化常见问题诊断。旨在帮助岩土工程颗粒材料研究者掌握从参数调试到破坏模拟的核心操作,提升数值模拟的准确性效率。 阅读详情

409. 最长回文串

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意:
假设字符串的长度不会超过 1010。

示例 1:
输入:
"abccccdd"

输出:	7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7

分析:给定一个字符串,找可以形成的最长的回文串,回文串的特点**:如果回文串是偶数个字符,则每个字符应该出现偶数遍,如果回文串是奇数个字符,则可以视为最中间的一个字符出现奇数遍,其他每个字符出现偶数遍**。因此,这个问题就简化为:出现次数为偶数的字符共到底有多少个(求的是和)。我们可以设置一个哈希来进行计数。具体求和时,奇淫巧计颇多,在此可以考虑其中之一:如果某个字符出现的次数为奇数,则计数为奇数-1,如果为偶数则全计数。因此,如果最终的和小于给定字符串的长度,则说明还可以加一个放中间,如果等于说明这是偶数个。 判断偶数可以用 a&1==0的方式判断

class Solution {
public:
    int longestPalindrome(string s) 
    {
        int c[128];
        for(int i=0;i<128;i++)
            c[i]=0;
        int result=0;
        for(int i=0;i<s.length();i++)
            c[s[i]]++;  //将对应的HASH值++
        for(int i=0;i<128;i++) //统计数量
            result+=((c[i]&1)==0?c[i]:(c[i]-1)); //偶数则取自身,奇数则取奇数-1
        return result==s.length()?result:result+1; //字符串全用的话则返回result,否则再在中间加一个字符
    }
};
290. 单词规律

给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。

示例1:
输入: pattern = "abba", str = "dog cat cat dog"
输出: true
示例 2:
输入:pattern = "abba", str = "dog cat cat fish"
输出: false
示例 3:
输入: pattern = "aaaa", str = "dog cat cat dog"
输出: false
示例 4:
输入: pattern = "abba", str = "dog dog dog dog"
输出: false

分析:这个规律实际就是pattern中的字符和 str 中的单词的一一对应关系。因此可以用HASH表示二者的关系,思路如下:

  • 设置单词到pattern字符的HASH映射,同时使用一个used数组表示pattern是否被使用
  • 遍历str,通过空格拆分单词,每拆分一个单词,pattern字符也向前移动一位
    • 如果单词没有出现在HASH表
      • 如果当前的pattern已经被使用,则返回false
      • 否则的话新建立一个从此单词到该pattern的映射,将pattern对应的used标记为使用
    • 如果单词出现在HASH表
      • 如果当前的单词在HASH表中对应的字符不是当前的字符,返回false
  • 如果单词个数和pattern字符个数不匹配,则返回false
class Solution {
public:
    bool wordPattern(string pattern, string str) 
    {
        map<string,char> MAP;  //pattern到char的一个映射
		bool used[128];
		for(int i=0;i<128;i++)
			used[i]=false;  //初始化used
		int pos=0; //存储当前的位置 
		string word; //存储当前的单词
		str.push_back(' ');//加一个空格便于分割
		for(int i=0;i<str.length();i++)
		{
			if(str[i]!=' ') 
				word+=str[i]; //记录
			else  //说明已经分割出一个单词 
			{
				if(MAP.find(word)==MAP.end()) //没找到
				{
					if(used[pattern[pos]]) return false; //该字符已经被使用 
					else 
					{     //建立映射,将其标记为已经使用 
						MAP[word]=pattern[pos];
						used[pattern[pos]]=true;	
					}	
				}
				else  //找到了该映射 
				{
					if(MAP[word]!=pattern[pos]) return false;
				} 
				word=""; //每判断完一个单词记得将word和pos更新 
				pos++;
			}	
		}
		if(pos!=pattern.length()) return false;
		return true;
    }
};
205. 同构字符串

给定两个字符串 s 和 t,判断它们是否是同构的。

如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。

所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

示例 1:
输入: s = "egg", t = "add"
输出: true
示例 2:
输入: s = "foo", t = "bar"
输出: false
示例 3:
输入: s = "paper", t = "title"
输出: true

方法一:既然都是字符,则可以充分利用STL中的优质函数,思路:遍历s和t时候,每个位置出现的字符,必须首次出现的位置相同,否则就不同构。

class Solution 
{
     public:
     bool isIsomorphic(string s, string t) 
     { 
         for(int i=0;i<s.size();i++)
             if(s.find(s[i])!=t.find(t[i])) 
                return false; 
         return true; 
     } 
};

方法二:与上个题思路一致

class Solution {
public:
    bool isIsomorphic(string s, string t) 
    {
        map<char,char> MAP;  //从s到t的映射 
        if(s.length()!=t.length()) return false;
		bool used[128];  //标记t中字符是否被使用 
		for(int i=0;i<128;i++)
			used[i]=false;  //初始化used
		int pos=0; //存储当前的位置 
		for(int i=0;i<s.length();i++)
		{
			if(MAP.find(s[i])==MAP.end()) //没找到
			{
				if(used[t[pos]]) return false; //该字符已经被使用 
				else 
				{     //建立映射,将其标记为已经使用 
					MAP[s[i]]=t[pos];
					used[t[pos]]=true;	
				}	
			}
			else  //找到了该映射 
			{
				if(MAP[s[i]]!=t[pos]) return false;
			}  
			pos++;
		}			
		return true;
    }
};
49. 字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

分析:该题关键,也就是如何建立一个HASH函数,使得字符相同的字符串映射到一起。设置一个 string->[string]的映射。

每次判断字符时利用临时变量将其排序后的结果存储,如果排序后的字符存在于HASH中,则将其加入到对应的[string]中,否则创建新的映射,将其加入。

class Solution {
public:
    vector<vector<string> > groupAnagrams(vector<string>& strs) 
	{
        map<string,vector<string> > MAP;//映射
		vector< vector<string> > result;
		for(int i=0;i<strs.size();i++)
		{
			string str=strs[i];
			sort(str.begin(),str.end());
			if(MAP.find(str)==MAP.end()) //没找到
			{
				vector<string> temp;
				MAP[str]=temp;		
			}
			MAP[str].push_back(strs[i]); //将其加入到对应的str[i] 
		 }
		 map<string,vector<string> >::iterator it;
		 for(it=MAP.begin();it!=MAP.end();it++)
		 	result.push_back(it->second);
		return result; 
    }
};

补充:由于是根据一个字符串中出现字符的各种数量进行的聚类,因此可以**制定一个向量映射 string->一个26长度的向量,26个位置分别存储string中每个字符出现的次数。**因此,将映射相同的添加到同一个[string],实际上,可以视为 **string->向量->[string]**的映射关系。具体代码不做详述,与上述类似,可以建立一个向量到[string]的映射,每次将字符串变为向量(上述方法是变为排序后的字符串),之后步骤相同。

3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

分析:通常涉及到字串的问题,常用滑动窗口法

大体思路如下:

  • 设置一个记录字符数量的HASH表,简单的用 char[128] 表示即可,用于判断是否已经有重复
  • 设置两个指针(实际上就是两个标记位置),一个作为begin,一个作为end,指向当前所扫描的字串头和尾
  • 每次固定begin,end向后扫描,扫描过程中更新HASH表,如果扫描到某个end时中发现出现过该字符,说明以当前begin为头的字串至多这么长,更新result为max(result,当前字串长度)
  • 需要移动begin位置(此时用到了滑动窗口),begin向后移动,同时更新HASH(每过一个字符对应减1),直至end所指的字符不在HASH中,则重新固定了begin,重复上个步骤。
class Solution {
public:
    int lengthOfLongestSubstring(string s) 
	{
    	int begin=0,end=0;
		int MAP[128]={0};  //作为HASH表 
		int result=0;
		for(end=0;end<s.length();end++) //移动end
		{
			MAP[s[end]]++; //遍历到了end
			if(MAP[s[end]]==1) //说明字串中没有出现过该字符
			{
				result=max(end-begin+1,result);
			}
			else //有重复就需要滑动窗口
			{
				while(MAP[s[end]]>1) //begin右移直至将end处相同字符跳过 
				{
					MAP[s[begin]]--; //将对应的MAP减1 
					begin++;	
				}	
			} 
		}
		return result; 
    }
};
187. 重复的DNA序列

所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。

编写一个函数来查找 DNA 分子中所有出现超过一次的 10 个字母长的序列(子串)。

示例:
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC", "CCCCCAAAAA"]

分析:暴力HASH解法。每次取一个长度为10的序列,通过HASH记录其数量,如果其之前已经出现过一次,即对应的HASH等于1,则将其加入(加入后将HASH更新为2,这样之后遍历到相同的字符时候,我们可以知道已经将其加入到答案序列了,跳过即可,省去了判断是否在答案序列中的步骤),如果该字符没有出现,则建立HASH,映射的值为1,表示出现一次。遍历至字串字符串尾部到达原字符串尾部停止。

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) 
	{
		map<string,short> MAP; //记录string次数的映射
		vector<string> result; //存储答案
		for(int i=0;i<s.length();i++)
		{
            string word=s.substr(i,10);  //获取s的以i起始长度为10的序列
			if(MAP[word]==1)  
				result.push_back(word); //添加
			MAP[word]++;	
		}
		return result; 
    }
};

该题具体的优化策略,更多的不是在算法层面,而是将四种字符映射为 00 01 10 11,将问题转化到位运算,从而使程序运行时间变得更快。

76. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

说明: 如果 S 中不存这样的子串,则返回空字符串 “”。 如果 S 中存在这样的子串,我们保证它是唯一的答案。

示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

分析:滑动窗口法

大致思路:

  • 设置一个窗口,可以用left 和 end标记
  • 不断增大right,直至窗口中的字符串符合要求
  • 缩小窗口,即向右滑动left,直至窗口不符合要求,此时的字符串即从最初left到现在right的符合条件的最短字符串。调整begin,重复操作。
  • 期间一直判断窗口是否减小,如果小于之前保留的最小值,则存储新的最小覆盖字串。

通常滑动窗口问题,都是完成目标后就开始调整窗口大小,直到尽可能达到目前最优。然后继续调整窗口。

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char, short> map;  //映射
        for (auto c : t) map[c]++;  //建立关于t的映射
        int left = 0, cnt = 0, maxlen = s.size() + 1, start = left;
        for (int i = 0; i < s.size(); ++i) 
        {
            if (--map[s[i]] >= 0) ++cnt;
            while(cnt == t.size()) 
            {
                if (maxlen > i - left + 1) 
                {
                    maxlen = i - left + 1;
                    start = left;
                } 
                if (++map[s[left]] > 0) cnt--;
                left++;
            }
        }
        return maxlen == s.size() + 1 ? "" : s.substr(start, maxlen);
    }
};

如何选择StandardScaler、MinMaxScaler和RobustScaler做标准化的对比解释和示例代码 选择合适的标准化方法取决于数据的特点和需求。如果数据分布接近正态分布且无异常值,可以使用。如果需要将数据映射到特定范围内并保持相对关系,可以使用。如果数据中存在异常值或离群点,可以使用进行鲁棒标准化。在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,StandardScaler表现更好(避免不同量纲对方差、协方差计算的影响);在不涉及距离度量、协方差、数据不符合正态分布、异常值较少的时候,可使用MinMaxScaler。 阅读详情

相关推荐

ADS笔记,新旧两组仿真数据进行绘图和列表对比

原理图器件参数的不同,怎么进行对比观看,操作如下。

彭辉荣的博客 3807

LeetCode哈希表(哈希集合,哈希映射)

哈希表是一种使用哈希函数组织数据,以支持快速插入和搜索的数据结构。 有两种不同类型的哈希表:哈希集合和哈希映射。 哈希集合是集合数据结构的实现之一,用于存储非重复值。 哈希映射是映射 数据结构的实现之一,用于存储(key, value)键值对。

ji_meng的博客 2247

华为OD机试双机位C卷:完美走位 (C++/C/Py/Java/Js/GO)

华为OD机试双机位C卷 完美走位, 提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机考 完美走位, 华为OD机试 完美走位。

qq_45776114的博客 1694

LeetCode 1153. 字符串转化(哈希)

文章目录1. 题目2. 解题 1. 题目 给出两个长度相同的字符串,分别是 str1 和 str2。请你帮忙判断字符串 str1 能不能在 零次 或 多次 转化后变成字符串 str2。 每一次转化时,将会一次性将 str1 中出现的 所有 相同字母变成其他 任何 小写英文字母(见示例)。 只有在字符串 str1 能够通过上述方式顺利转化为字符串 str2 时才能返回 True,否则返回 False。​​ 示例 1: 输入:str1 = "aabcc", str2 = "ccdee" 输出:true 解释:将

Michael是个半路程序员 1434

哈希表(知识点+leetcode)以及字符串哈希

哈希表是散列表,就是通过关键码值而直接进行访问的一种数据结构哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素其内部由一个个key:value 样式的键值对组成。哈希表中的key通过哈希函数得到内存地址,然后将key和value放到对应的内存地址,从而实现通过key获取Value的方式哈希碰撞:2个不同的key通过哈希函数(hash function)得到了相同的内存地址,也就是是内存地址已经被一个占用了,解决方法是将其中之一变为链表结构,使用next指向。

wh233z的博客 2341

12/21 学习笔记 hashcode String

1.看了有关immutable class的资料,  An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creat

yanrui92的专栏 436

LeetCode 哈希表字符串

哈希表:根据关键字值(key)直接进行访问的数据结构,通过把关键字的值映射到表的一个位置来直接访问,以加快查找速率。(有点空间换时间) 字符哈希 ASCII码:0-127,在一个char[128]的数组中即可对所有字符进行hash。 例如第x个位置值为y,那表示ASCII=x的字符共出现了y次。 String str = "abd"; char[] str_char = str.toCharArray(); for(char i : str_char){...

Robin_812656252的博客 212

十连发!经典leetcode算法题解分享(哈希表)

淦就完事了~

yehongzhi1994的博客 1275

Leetcode刷题指南和top100题目

原文链接:https://blog.csdn.net/qq_39521554/article/details/79160815 参考博文:https://blog.csdn.net/mmc2015/article/details/87200435 一、刷题方法 方法一:按照题目出现频率刷题 顺序参考文章最后的部分 方法二:标签法 按照网站给大家排列的不同tags,起到模块化的复习和学习作用。举...

lingpy的博客 6万+

如何优雅地刷力扣 LeetCode - Easy

App > LeetCode > 题库 > 题解。

媛媛 848

【GitHub项目推荐--LeetCodeAnimation:用动画的形式呈现LeetCode题目思路

​​ 是一个创新的开源项目,由MisterBooo(吴师兄)创建,致力于用动画的形式演示LeetCode题目的解题思路。该项目通过直观的动画可视化,帮助开发者更好地理解和掌握算法数据结构的核心概念,让抽象的算法变得生动易懂。🔗 ​GitHub地址🚀 ​核心价值​:动画演示 · 算法可视化 · 学习辅助 · 直观理解​项目背景​:​学习痛点​:解决算法学习抽象难懂的问题​视觉学习​:利用动画提升学习效果和理解深度​创新教学​:创新的算法教学方法​长期规划​:3-4年完成所有题目动画化​。

j8267643的博客 1049

分门别类刷leetcode——哈希表字符串(C++实现)

复习哈希表 使用哈希统计字符串中的字符个数 #include&lt;stdio.h&gt; #include&lt;string&gt; int main(int argc, char *argv[]) { int char_map[128] = { 0 }; std::string str = "abcdefgaaxxy"; for (auto i : str...

一直走,不要回头 1034

leetcode 1737 解题思路及注释code 贪心

备忘录 最近在刷leetcode,好不容易搞懂一道题,还是希望记录下来,以防之后忘记,也希望可以分享给大家思路题目要求 给你两个字符串 a 和 b ,二者均由小写字母组成。一步操作中,你可以将 a 或 b 中的 任一字符 改变为 任一小写字母 。 操作的最终目标是满足下列三个条件 之一 : a 中的 每个字母 在字母表中 严格小于 b 中的 每个字母 。 b 中的 每个字母 在字母表中 严格小于 a 中的 每个字母 。 a 和 b 都 由 同一个 字母组成。 返回达成目标所需的 最少 操作数

厚积而薄发 369

[Leetcode][广度优先/哈希表/纯思路]相关题目汇总/分析/总结

题目汇总 以下链接均为我博客内对应博文,有解题思路和代码,不定时更新补充。 目前范围:Leetcode前150题 BFS广度优先题目 Word Ladder/Word Ladder II/单词接龙/单词接龙 II 难 给定一个起始字符串和一个目标字符串,现在将起始字符串按照特定的变换规则转换为目标字符串,求最少要进行多少次转换。转换规则为每次只能改变字符串中的一个字符,且...

蛮三刀酱 1015

LeetCode刷题指南:用C语言征服50道经典算法

LeetCode 作为全球知名的算法练习平台,提供了大量经典算法题目。使用 C 语言刷题,不仅可以加深对算法的理解,还能提升对底层编程的掌握。本指南将带领你用 C 语言征服 50 道经典算法题,为你的技术能力提升助力。

星辰夜语的博客 1912

【简单】力扣算法题解析LeetCode266:回文排列

回文重构判定:统计字符频率,奇数频率字符数≤1即可。使用数组计数法,遍历字符串统计各字符出现次数,再检查奇数频率字符数量是否满足条件。Java实现中,128长度的数组覆盖ASCII字符集,通过位运算高效判断奇偶性,优化提前终止条件。

ylumwd的博客 1004

力扣:438. 找到字符串中所有字母异位词 题解

C++解法:【滑动窗口 + 哈希表】,小白可入门!

weixin_62021811的博客 634

LeetCode 第 291 场周赛 题解及思路

LeetCode 第 291 场周赛 题解及思路 6047. 移除指定数字得到的最大结果 6048. 必须拿起的最小连续卡牌数 6049. 含最多 K 个可整除元素的子数组 6050. 字符串的总引力

weixin_46323890的博客 337

LeetCode面试经典150题:高效刷题面试突破指南

算法数据结构是计算机科学的核心基础,其原理应用贯穿软件开发全生命周期。通过系统化的题目训练,开发者可以掌握时间复杂度分析、空间复杂度优化等关键技术能力,这在技术面试和工程实践中都至关重要。LeetCode面试经典150题精选了数组、链表、树、动态规划等高频考点,采用三遍刷题法等科学训练方法,能有效提升解题思维。结合动态规划、滑动窗口等热词技术,本文详解了从基础概念到面试实战的完整路径,特别适合准备互联网大厂算法面试的工程师参考学习。

weixin_30562507的博客 409

[从零开始面试算法] (01/100) LeetCode 1. 两数之和:哈希表的亲密接触

摘要:本文通过LeetCode"两数之和"问题,详细解析了暴力解法哈希表优化方案。作者首先展示时间复杂度O()的双重循环暴力解法,随后引入哈希表(unordered_map)概念,通过"智能储物柜"的生动比喻解释了哈希函数的运作原理。最终给出C++最优解代码,利用哈希表将时间复杂度降至O(n),实现"空间换时间"的优化策略。文章不仅提供完整代码实现,还深入浅出地讲解了哈希表的核心机制和碰撞处理方法,适合算法初学者理解数据结构优化思路

2201_75993451的博客 1427

Leetcode 随笔】

摩尔投票算法的关键在于,如果一个数字的出现次数超过数组长度的一半,那么遍历数组时,这个数字出现的次数其他所有数字出现次数的差,最终一定是大于 0 的。给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得红色排在前面,蓝色排在后面,白色排在中间。我们需要维护三个指针,分别指向当前遍历到的位置、0 的最右位置和 2 的最左位置。如果数组 mid 位置的值为 2,交换 mid 和 high 位置的元素,但只将 high 指针向左移动一位(因为新交换过来的元素还未判断)。

种一棵树,最好的时间是十年前,其次是现在。 667

leetcode刷题日记——同构字符串

【代码】leetcode刷题日记——同构字符串

qq_46582619的博客 560

WIN10可用版迅雷5绿色防敏感资源_可下载敏感.zip

WIN10可用版迅雷5绿色防敏感资源_可下载敏感.zip,迅雷

区域影像中心系统建设方案书.docx.pdf

区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf区域影像中心系统建设方案书.docx.pdf

上一篇: leetcode 经典 图相关题目(思路、方法、code)
下一篇: leetcode 经典动态规划DP算法题目(思路、方法、code)
coding丁
博客等级 码龄8年 382粉丝 147原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值