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

本文介绍了使用哈希表解决LeetCode中关于字符串的几道经典题目,包括最长回文串、单词规律、同构字符串、字母异位词分组、无重复字符的最长子串、重复的DNA序列和最小覆盖子串。通过哈希表统计字符出现次数,实现滑动窗口等方法,巧妙地解决了这些问题。
摘要由CSDN通过智能技术生成

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(' ')<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值