567.字符串的排列

难度:中等

目录

一、问题描述

二、解题思路

1、思路

三、解题

1、代码实现

2、时间复杂度 and 空间复杂度


一、问题描述

这里直接采用LeetCode上面的问题描述。

给你两个字符串 s1 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false

换句话说,s1 的排列之一是 s2 子串

下面给出是示例:

提示:

  • 1 <= s1.length, s2.length <= 104
  • s1 和 s2 仅包含小写字母

二、解题思路

1、思路

对于这种一个字符串是否包含另一个字符串的所有排列的题目,可以采用滑动窗口+统计被包含所有字符的个数,进行判断。

        只要维护两个容器 nums1nums2nums1 代表着字符串 s1 中所有的字符的个数,而 nums2 则代表着滑动窗口在字符串 s2 上滑动时的字符串个数,当然这里的滑动窗口的大小为 s1 的大小。只要判断 nums1 是否与 nums2 相等即可。如果滑动过程中 nums1 nums2相等,那么说明在字符串 s2 中肯定包含了 s1 的排列组合。如果滑动窗口滑动到 s2 的末尾,nums1nums2都没有相等的话,那么直接return false即可。

三、解题

1、代码实现

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        //如果s1的长度 大于 s2的长度 那么s2不可能包含s1的排列
        if(s1.length() > s2.length()){
            return false;
        }
        int n = s1.length(), m = s2.length();
        //因为只有小写字母所以最多只有26 个字母 初始化两个容器统计字母的个数
        vector<int> nums1(26,0), nums2(26,0);
        //这里统计了 s1 和 s2 前n个字母的个数
        for(int i = 0; i < n; i++){
            nums1[s1[i] - 'a']++;
            nums2[s2[i] - 'a']++;
        }
        //若是 s1 与 s2 前n个字母的个数相等,那么说明s2包含了s1的排列
        if(nums1 == nums2){
            return true;
        }
        //这里滑动窗口进行判断,每次维持nums2 中的字母个数与 nums1的个数相等,
        //每次进行新字符加入,并且减去前面一个字符
        for(int i = n; i < m; i++){
            nums2[s2[i] - 'a']++;
            nums2[s2[i - n] - 'a']--;
            //滑动窗口判断,如果nums1 == num2 那么说明 s2包含了 s1 的排列
            if(nums1 == nums2){
                return true;
            }
        }
        return false;
    }
};

2、时间复杂度 and 空间复杂度

时间复杂度:O(n),n为s2的长度。

空间复杂度: O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Alkaid_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值