剑指 Offer II 015. 字符串中的所有变位词

剑指 Offer II 015. 字符串中的所有变位词

一、题目

原题链接:剑指 Offer II 015. 字符串中的所有变位词

1.题目描述

给定两个字符串 sp,找到 s 中所有 p变位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

变位词 指字母相同,但排列不同的字符串。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的变位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的变位词。

示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的变位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的变位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的变位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • sp 仅包含小写字母

注意:本题与主站 438 题相同: https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

2.基础框架

C++基础框架代码如下:

vector<int> findAnagrams(string s, string p) {
}

3.解题思路

  • 题目分析
  1. 题目目标是返回所有变位词子串的起始下标。
  2. 变位词字符串也就是在一个字符串中的元素个数相同且种类相同,且排列顺序不同的字符串。
  3. 定义两组哈希数组s_recq_rec,其中s_rec数组作为滑动窗口记录元素的作用。如果当前的滑动窗口数组s_rec等于q_rec数组,那么说明当前的滑动窗口中的子串为变位词字符串
  4. 每次向右移动滑动窗口,只需要移出窗口左边的元素,窗口右边移入一个新的元素。对应的操作就是窗口左边元素在s_rec中索引的位置减一,右边的新元素在s_rec中索引的位置加一。
  5. 如果找到变位词字符串,则将滑动窗口最左边的元素作为子串起始位置,存储到res数组中,当遍历结束后,返回res数组,res数组表示的是s字符串中所有变位词子字符串的起始位置。
  • 实现代码:

    vector<int> findAnagrams(string s, string p) {
        if (s.length() < p.length()) return {};	// 不存在变位词字符串
        vector<int> s_rec(26, 0);
        vector<int> p_rec(26, 0);
        vector<int> res;
        int len = p.size();
        int i;
        for (i = 0; i < p.size(); i++)
        {
            ++s_rec[s[i] - 'a'];
            ++p_rec[p[i] - 'a'];
        }
        if (s_rec == p_rec) res.push_back(0); // 以0为起始节点的s子字符串是否为变位词字符串
        for (i = 1; i < s.size() - len + 1; i++)
        {
            --s_rec[s[i - 1] - 'a'];
            ++s_rec[s[i + len - 1] - 'a'];
            if (s_rec == p_rec)	// 当前滑动窗口是否为变位词字符串
                res.push_back(i);
        }
        return res;
    }
    

二、知识点总结

  本次解题使用了 h a s h hash hash 和 滑动窗口,滑动窗口每次都是左边减一个元素,右边加一个元素,不再需要对窗口中的中间部分元素进行重新统计,从而减少了操作次数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值