⭐算法入门⭐《双指针》中等02 —— LeetCode 567. 字符串的排列

🙉饭不食,水不饮,题必须刷🙉

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

LeetCode 太难?先看简单题!
🧡《C语言入门100例》🧡

数据结构难?不存在的!
🌳《画解数据结构》🌳

闭关刷 LeetCode,剑指大厂Offer!
🌌《LeetCode 刷题指引》🌌

LeetCode 太简单?算法学起来!
💜《夜深人静写算法》💜

一、题目

1、题目描述

  给定两个长度小于 1 0 5 10^5 105 的字符串 s 1 s_1 s1 s 2 s_2 s2,写一个函数来判断 s 2 s_2 s2 是否包含 s 1 s_1 s1 的排列。即 第一个字符串的排列之一第二个字符串子串
  样例输入1: s 1 s_1 s1 = “ a b ab ab s 2 s_2 s2 = “ e i d b a o o o eidbaooo eidbaooo
  样例输出1: t r u e true true
  样例输入2: s 1 s_1 s1 = “ a b ab ab s 2 s_2 s2 = “ e i d b z a o o o eidbzaooo eidbzaooo
  样例输出2: f a l s e false false

2、基础框架

  • c++ 版本给出的基础框架代码如下:
class Solution {
public:
    bool checkInclusion(string s1, string s2) {
    }
};
  • 其中 string是 C++ 的 STL 中的模板类,可以用来做字符串的各种操作;

3、原题链接

LeetCode 567. 字符串的排列

二、解题报告

1、思路分析

  • 用 双指针 配合 哈希表,首先用一个hash表来记录 s 1 s_1 s1 中每个字符的出现次数。然后对 s 2 s_2 s2 字符串进行双指针算法,对于选取的子串,如果能和 s 1 s_1 s1 的每个字符的数量完全匹配,那就能满足题目的条件。
  • 双指针算法又叫尺取法,详细的算法可以参考:夜深人静写算法(二十八)- 尺取法

2、时间复杂度

  • 两个指针都只会递增各一次,所以时间复杂度为 O ( n ) O(n) O(n)

3、代码详解

class Solution {
    int hash[257];
public:
    bool checkInclusion(string s1, string s2) {
        memset(hash, 0, sizeof(hash));
        for(int i = 0; i < s1.length(); ++i) {
            ++hash[ s1[i] ];                   // (1)
        }
        int len = s2.length();                 // (2)
        int i = 0, j = -1;
        while(j++ < len - 1) {                 // (3)
            --hash[ s2[j] ];                   // (4)
            while(hash[ s2[j] ] < 0) {         // (5)
                ++hash[ s2[i] ];               // (6)
                ++i;
            }
            if(j - i + 1 == s1.length()) {     // (7)
                return true;
            }
        }
        return false;
    }
};
  • ( 1 ) (1) (1) 代表一开始是空串;
  • ( 2 ) (2) (2) 之所以要这么做,是因为s.length()是无符号整型,当 j == -1的情况为无符号整型的最大值,永远都无法进入下面的while(j++ < len - 1)这个循环;
  • ( 3 ) (3) (3) 尝试向右移动 右指针;
  • ( 4 ) (4) (4) 对新加入的字符,进行计数;
  • ( 5 ) (5) (5) 合法性判定:选取的 s 2 s_2 s2 子串中的各个 s 1 s_1 s1 中字符个数必须不能超过 s 1 s_1 s1 的个数;
  • ( 6 ) (6) (6) 尝试向右移动 左指针;
  • ( 7 ) (7) (7) 如果选取的 s 2 s_2 s2 合法子串长度正好和 s 1 s_1 s1 相等,则表明找到了满足题目条件的子串,返回true

三、本题小知识

尺取法问题大同小异,是可以整理出模板的。


评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值