旺崽的博客

要么天赋异禀,要么天道酬勤

0%

LeetCode 567 字符串的排列

题目链接

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例 1:

1
2
3
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").

示例 2:

1
2
输入: s1= "ab" s2 = "eidboaoo"
输出: False

这题暴力的复杂度达到了阶乘级别,显示不可取,首先我们考虑如果有两个等长的字母字符串,如何判断其中一个是另一个的排列~
其实换种思路就简单了,我们可以统计每个字母出现的次数,然后一一比较每个字母的次数是否一样即可,假设字符串长为 $n$,则暴力的复杂度为 $O(n!)$,优化后复杂度变为 $O(26*n)$~
那如果两个字符串长度不相等(一个为 $m$,一个为 $n$)呢,很简单,我们开设一个大小为 $m$ 的滑窗即可,每次右移只需要将左端点弹出,右端点压入即可,AC代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
private:
int cnt1[30] = {0}, cnt2[30] = {0};
public:
bool check() {
int flag = 1;
for (int i = 0; i < 26; i++) {
if (cnt1[i] != cnt2[i]) flag = 0;
}
return flag;
}

bool checkInclusion(string s1, string s2) {
if (s1.size() > s2.size()) return 0;
int n = s1.size(), m = s2.size();
for (int i = 0; i < n; i++) cnt1[s1[i] - 'a']++, cnt2[s2[i] - 'a']++;
if (check()) return 1;
for (int i = n; i < m; i++) {
cnt2[s2[i - n] - 'a']--;
cnt2[s2[i] - 'a']++;
if (check()) return 1;
}
return 0;
}
};