【算法】滑动窗口——找到字符串中所有字母异位词

简介: 【算法】滑动窗口——找到字符串中所有字母异位词

本节博客是对题目——找到字符串中所有字母异位词的从读题到代码实现以及优化的详细解读,有需要借鉴即可。



1.题目

题目链接:LINK

首先来解释一下什么是异位词,所谓“异位词”,即不要求字母顺序的字符串。

其实这个题目思路很快就可以想到,拿个left,right指针,使两者间距始终等于p字符串长度,再与p字符串对比一下就行了。

说起来这个思路那不就是“滑动窗口”嘛,因为两个指针都是从左到右移动的。

那异位怎么进行比较的呢?可以搞一个哈希数组进行依次比较即可。

2.滑动窗口 + 哈希数组

于是,我们可以写出下面的代码:

class Solution
{
public:
 bool check(int* p, int*s)
 {
    for(int i = 0;i < 128;i++)
    {
        if(p[i] != s[i])
        {
            return false;
        }
    }
    return true;
 }
 vector<int> findAnagrams(string s, string p) 
 {
    //统计一下p字符串的字符信息
    size_t len = p.size();
    int hash_p[128] = {0};
    for(int i = 0;i<len;i++)
    {
        hash_p[p[i]]++;
    }
    int n = s.size();
    int hash_s[128] = {0};
    vector<int> ret;
    //滑动窗口
    for(int right = 0,left = 0;right < n;right++)
    {
        //进窗口
        hash_s[s[right]]++;
        //判断,出窗口
        if(right - left + 1 > len)
        {
            hash_s[s[left]]--;
            left++;
        }
        //更新结果
        if(check(hash_p,hash_s) && right - left + 1 == len)
        {
            ret.push_back(left);
        }
    }
    return ret;
 }
};

实际上,题目中明确说只有小写字母,所以说可以把哈希数组搞成26个的:

class Solution
{
public:
    bool check(int* p, int* s)
    {
        for (int i = 0; i < 26; i++)
        {
            if (p[i] != s[i])
            {
                return false;
            }
        }
        return true;
    }
    vector<int> findAnagrams(string s, string p)
    {
        //统计一下p字符串的字符信息
        size_t len = p.size();
        int hash_p[26] = { 0 };
        for (int i = 0; i < len; i++)
        {
            hash_p[p[i] - 'a']++;
        }
        int n = s.size();
        int hash_s[26] = { 0 };
        vector<int> ret;
        //滑动窗口
        for (int right = 0, left = 0; right < n; right++)//"cbaebabacd"
        {
            //进窗口
            hash_s[s[right] - 'a']++;
            //判断,出窗口
            if (right - left + 1 > len)
            {
                hash_s[s[left] - 'a']--;
                left++;
            }
            //更新结果
            if (check(hash_p, hash_s) && right - left + 1 == len)
            {
                ret.push_back(left);
            }
        }
        return ret;
    }
};

3.异位词优化

虽然这样可以解题,不过问题是如果是比较的是比较多的字符呢?不仅仅是26的小写字母。我想如果这样比较,复杂度瞬间就会上来了。

所以,在比较异位词时,我们需要再优化一下:

思路大致是下面这样的,如下:

所以,可以优化为下面代码:

class Solution
{
public:
    vector<int> findAnagrams(string s, string p)
    {
        //统计一下p字符串的字符信息
        size_t len = p.size();
        int hash_p[26] = { 0 };
        for (int i = 0; i < len; i++)
        {
            hash_p[p[i] - 'a']++;
        }
        int n = s.size();
        int count = 0;//count标识有效字符的个数,即p字符串的长度
        int hash_s[26] = { 0 };
        vector<int> ret;
        //滑动窗口
        for (int right = 0, left = 0; right < n; right++)//"cbaebabacd"
        {
            //进窗口
            hash_s[s[right] - 'a']++;
            if(hash_s[s[right]-'a'] <= hash_p[s[right]-'a'])count++;//进窗口,维护有效字符个数
            //判断,出窗口
            if (right - left + 1 > len)
            {
                if(hash_s[s[left] - 'a'] <= hash_p[s[left] - 'a'])count--;//出窗口,维护有效字符个数
                hash_s[s[left] - 'a']--;
                left++;
            }
            //更新结果
            if (count == len)
            {
                ret.push_back(left);
            }
        }
        return ret;
    }
};

4.总结

其实总结一下来看,这个题目除了异位词问题之外也没什么东西,这个题目是一个典型的“固定长度的滑动窗口”,要解出来难度不大。


EOF

相关文章
|
2月前
|
算法
【算法】滑动窗口——最大连续1的个数
【算法】滑动窗口——最大连续1的个数
|
2月前
|
算法
【算法】滑动窗口——最小覆盖子串
【算法】滑动窗口——最小覆盖子串
|
2月前
|
算法
【算法】滑动窗口——将x减到0的最小操作数
【算法】滑动窗口——将x减到0的最小操作数
|
15天前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
41 1
两个字符串匹配出最长公共子序列算法
|
16天前
|
算法
条件运算符与条件if的姻缘,打擂台算法和大小写字母转换,if逻辑避坑
条件运算符与条件if的姻缘,打擂台算法和大小写字母转换,if逻辑避坑
13 1
|
2月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
2月前
|
算法 容器
【算法】滑动窗口——串联所有单词的子串
【算法】滑动窗口——串联所有单词的子串
|
2月前
|
算法
【算法】滑动窗口——水果成篮
【算法】滑动窗口——水果成篮
|
17天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真
### 算法简介 1. **算法运行效果图预览**:展示算法效果,完整程序运行后无水印。 2. **算法运行软件版本**:Matlab 2017b。 3. **部分核心程序**:完整版代码包含中文注释及操作步骤视频。 4. **算法理论概述**: - **MSER**:用于检测显著区域,提取图像中稳定区域,适用于光照变化下的交通标志检测。 - **HOG特征提取**:通过计算图像小区域的梯度直方图捕捉局部纹理信息,用于物体检测。 - **SVM**:寻找最大化间隔的超平面以分类样本。 整个算法流程图见下图。
|
1天前
|
存储
基于遗传算法的智能天线最佳阵列因子计算matlab仿真
本课题探讨基于遗传算法优化智能天线阵列因子,以提升无线通信系统性能,包括信号质量、干扰抑制及定位精度。通过MATLAB2022a实现的核心程序,展示了遗传算法在寻找最优阵列因子上的应用,显著改善了天线接收功率。

热门文章

最新文章