难度:中等
目录
一、问题描述
二、解题思路
1、思路
三、解题
1、代码实现
2、时间复杂度 and 空间复杂度
一、问题描述
这里直接采用LeetCode上面的问题描述。
给你两个字符串 s1
和 s2
,写一个函数来判断 s2
是否包含 s1
的排列。
如果是,返回 true
;否则,返回 false
。
换句话说,s1
的排列之一是 s2
的 子串 。
下面给出是示例:
提示:
1 <= s1.length, s2.length <= 104
s1
和s2
仅包含小写字母
二、解题思路 1、思路
对于这种一个字符串是否包含另一个字符串的所有排列的题目,可以采用滑动窗口+统计被包含所有字符的个数,进行判断。
只要维护两个容器 nums1 与 nums2 ,nums1 代表着字符串 s1 中所有的字符的个数,而 nums2 则代表着滑动窗口在字符串 s2 上滑动时的字符串个数,当然这里的滑动窗口的大小为 s1 的大小。
只要判断 nums1 是否与 nums2 相等即可。
如果滑动过程中 nums1 与 nums2相等,那么说明在字符串 s2 中肯定包含了 s1 的排列组合。
如果滑动窗口滑动到 s2 的末尾,nums1 与 nums2都没有相等的话,那么直接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的长度。
空间复杂度:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)