【笔记】LeetCode 3.无重复字符的最长字串、438.找到字符串中所有字母异位词---滑动窗口

本文介绍了滑动窗口算法在解决两个问题上的应用:一是寻找给定字符串中无重复字符的最长子串长度,二是找出字符串中所有与给定字符串p为异位词的子串及其起始索引。通过使用哈希表和unordered_map,简化了字符计数的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


滑动窗口

滑动窗口三步走:

  1. 在一定条件下,移动尾指针;
  2. 尾指针无法向前时,移动头指针直到符合条件;
  3. 记录符合要求的结果。

难点在于如何建立哈希表,下面两题哈希表的键值是字符,存储元素出现的次数。


一、无重复字符的最长字串

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

算法分析

经典的滑动窗口问题,此前做过一道类似的数字串的题目,这次做的字符串的题,使用数组也可过,但使用 unordered_map 应该更直观一点。做这道题的时候总是忘记左指针该怎么移动到重复元素的前面一个元素,需要记忆一下思路。

算法实现

class Solution {
public:
    int lengthOfLongestSubstring(string s) {

    int x=0,y=0,cnt,res=0;
    int h[50000]={0};
    // unordered_map<char,int> h;
    while(y<s.size()){
        while(y<s.size()&&h[s[y]]==0)  h[s[y]]++,y++;
        h[s[y]]--;
        cnt=y-x;
        if(cnt>res)   res=cnt;
        while(h[s[x]]==1) h[s[x]]--,x++;
        x++;
    }
        return res;
    }
};

二、找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。异位词:指由相同字母重排列形成的字符串(包括相同的字符串)。

算法分析

如何表示异位词相同是本体的关键,一开始我想把p的每个字符存储到 unordered_set 里面,比较在 s 的滑动窗口中的元素是否出现过,但要输出起始索引不好处理。建立哈希表,使用 vector 或者数组直接存储 p 和滑动窗口的每个字母出现的次数,如果次数相同则是异位词,似乎更简洁一点。

算法实现

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> res;
        if (s.size() < p.size()) return res; // 如果 s 的长度小于 p 的长度,直接返回空结果
        int plen = p.size(); 
        vector<int> vp(26, 0); // 存储 p 中每个字母出现的次数
        vector<int> vtmp(26, 0); // 存储滑动窗口中每个字母出现的次数
        
        for (auto x : p) vp[x - 'a']++; 
        
        for (int i = 0; i < s.size(); i++) { 
            if (i >= plen) // 如果超过 p 的长度,就要移动 head 指针
                vtmp[s[i - plen] - 'a']--; // 释放 head 指向的字符
            vtmp[s[i] - 'a']++; // 使用 tail 指向的字符
            if (vtmp == vp) // 如果两个数组相等,说明找到了一个异位词
                res.push_back(i - plen + 1); // 将 head 的值加入结果中
        }
        
        return res; 
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值