【题目描述】

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

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

​https://leetcode.cn/problems/permutation-in-string/description/​


【示例】

【LeeCode】567. 字符串的排列_滑动窗口


【代码】admin

超出内存限制 --> 可以根据字符统计来优化一下

class Solution {
public boolean checkInclusion(String str, String sss) {
if(str.length() == 0 || "".equals(str)){
return false;
}

List<String> list = new ArrayList<>();
list.add(str.charAt(0)+"");
for(int i = 1; i < str.length(); i++){
char c = str.charAt(i);
List<String> new_list = new ArrayList<>();
for (String x :list) {
new_list.add(x + c); // a b
new_list.add(c + x); // b a
for(int j = 1; j < x.length(); j++){
String tmp = x.substring(0, j) + c + x.substring(j);
new_list.add(tmp);
}
}
list = new_list;
}

for (String x : list) {
if(sss.contains(x)){
return true;
}
}
return false;
}
}


【代码】​​滑动窗口​

 

【LeeCode】567. 字符串的排列_i++_02

package com.company;
import java.util.*;

// 2023-2-27
class Solution {
public boolean checkInclusion(String s1, String s2) {
int len = s1.length();
int len2 = s2.length();
// 如果子串s1长度小于s2 则一定不是字串
if (len >len2) return false;
// 维护一个列表, 分别用于统计s1和s2中字符个数
int[] cn1 = new int[26];
int[] cn2= new int[26];
// 滑动窗口为len, 统计len中字符的个数
for (int i = 0; i < len; i++){
++cn1[s1.charAt(i) - 'a'];
++cn2[s2.charAt(i) - 'a'];
}
// 相等则一定是
if (Arrays.equals(cn1, cn2)) return true;
for (int i = len; i < len2; i++){
// 继续比较且维护len的窗口大小
++cn2[s2.charAt(i) - 'a'];
// 有进就有出, 否则大小不一
--cn2[s2.charAt(i - len) - 'a'];
if (Arrays.equals(cn1, cn2)) return true;
}
return false;
}
}
public class Test {
public static void main(String[] args) {
new Solution().checkInclusion("ab", "eidbaooo"); // 输出: true
new Solution().checkInclusion("ab", "eidboaoo"); // 输出: false
}
}