IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode 438 -> 正文阅读

[数据结构与算法]leetcode 438

思路一:滑动窗口+哈希数组

1.为两个字符串设置长度为26的哈希字母数组sdup[26]和pdup[26]

2.获得s串长度slen和p串长度plen

3.遍历p串,获得pdup

(1)遍历s串,维护一个元素个数为plen的字串t,维护其元素出现次数的哈希表sdup,也就是每遍历一个新的元素,在sdup数组中,将字串t第一个元素的记录-1,然后找到新元素的位置,相应记录+1;

(2)然后比较sdup和pdup是否相等,若相等,则将t的起始位置加入结果vector中

代码:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int plen=p.length();
        int slen=s.length();
        vector<int> res;
        vector<int> pdup(26,0);
        vector<int> sdup(26,0);
        for(int i=0;i<plen;i++)
        {
            pdup[p[i]-'a']++;
        }
        for(int i=0;i<slen;i++)
        {
            if(i>=plen)
                sdup[s[i-plen]-'a']--;
            sdup[s[i]-'a']++;
            int flag=0;
            for(int j=0;j<26;j++)
            {
                if(sdup[j]!=pdup[j])
                {
                    flag=1;
                    break;
                }
            }
            if(!flag)
                res.push_back(i-plen+1);
        }
        return res;
    }
};

思路二:可变长度滑动窗口+双指针

1.为两个字符串设置长度为26的哈希字母数组sdup[26]和pdup[26]

2.获得s串长度slen和p串长度plen

3.遍历p串,获得pdup

4.起始窗口左端left=0,右端=0

(1)遍历s串,维护一个变长字串t,每当遍历一个新的元素,记为cur_right,则在sdup中找到其相遇位置,对应记录+1

(2)当sdup[cur_right]>pdup[cur_right]时,这意味着t串中cur_right位置上的元素个数是多的,需要减少,我们通过从头开始遍历t串以减去t串中cur_right位置上相同元素以达到满足sdup=pdup,通过sdup[left]–,left++来实现,从而达到左窗口右移的效果。

(3)只要sdup[cur_right]>pdup[cur_right]存在,都会导致sdup!=pdup,这就意味着,此时t串仍然有多余重复元素,假设此时t串长度为tlen<=plen,如果当前t串的最右侧元素是多余重复元素,那么此时的left不可能是目标串的起点,最极端情况就是left==cur_right才满足sdup[cur_right]=pdup[cur_right]。

(4)当sdup[cur_right]<=pdup[cur_right],判断此时t长度是否刚好等于plen,若是,则找到一个匹配子串,则将t的起始位置加入结果vector中。

补充:对于(4)实际上如果sdup[cur_right]<pdup[cur_right],

此时t长度是否刚好不可能等于plen,因为至少还有一个元素没有满足个数要求。

代码:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int plen=p.length();
        int slen=s.length();
        vector<int> res;
        vector<int> pdup(26,0);
        vector<int> sdup(26,0);
        for(int i=0;i<plen;i++)
        {
            pdup[p[i]-'a']++;
        }
        int left=0;
        for(int i=0;i<slen;i++)
        {
            sdup[s[i]-'a']++;
            while(sdup[s[i]-'a']>pdup[s[i]-'a'])
            {
                sdup[s[left]-'a']--;
                left++;
            }
            if(i-left+1==plen)
            {
                res.push_back(left);
            }
        }
        return res;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:31:37  更:2021-10-09 16:32:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 13:20:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码