567.字符串的排列

567.字符串的排列,第1张

难度:中等

目录


一、问题描述


二、解题思路

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 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 空间复杂度

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


空间复杂度: 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/564856.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-06
下一篇 2022-04-06

发表评论

登录后才能评论

评论列表(0条)

保存