LeetCode567-字符串的排列

题目链接

英文链接:https://leetcode.com/problems/permutation-in-string/

中文链接:https://leetcode-cn.com/problems/permutation-in-string/

题目详述

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

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

示例1:

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

示例2:

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

注意:

  1. 输入的字符串只包含小写字母
  2. 两个字符串的长度都在 [1, 10,000] 之间

题目详解

滑动窗口,做法类似于 LeetCode438-找到字符串中所有字母异位词

方法一:固定窗口大小,每次移动一格,判断当前窗口是否满足条件。

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
26
27
28
29
30
31
32
33
public class LeetCode_00567 {

public boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) {
return false;
}
int[] map = new int[26];
for (int i = 0; i < s1.length(); ++i) {
++map[s1.charAt(i) - 'a'];
--map[s2.charAt(i) - 'a'];
}
if (allzeros(map)) {
return true;
}
for (int i = s1.length(); i < s2.length(); ++i) {
--map[s2.charAt(i) - 'a'];
++map[s2.charAt(i - s1.length()) - 'a'];
if (allzeros(map)) {
return true;
}
}
return false;
}

private boolean allzeros(int[] nums) {
for (int num : nums) {
if (num != 0) {
return false;
}
}
return true;
}
}

方法二:不固定窗口大小,优先满足条件,再判断当前窗口大小是否满足要求。

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
26
27
28
public class LeetCode_00567 {

public boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) {
return false;
}
int[] map = new int[26];
for (char c : s1.toCharArray()) {
++map[c - 'a'];
}
int size = s1.length();
int l = 0, r = 0;
while (r < s2.length()) {
if (--map[s2.charAt(r++) - 'a'] >= 0) {
--size;
}
while (size == 0) {
if (r - l == s1.length()) {
return true;
}
if (++map[s2.charAt(l++) - 'a'] > 0) {
++size;
}
}
}
return false;
}
}