滑动窗口相关算法
·
1、包含子串所有字符的最小窗口
public static String minWindow(String s, String t) {
if (s.length() < t.length()) {
return "";
}
char[] sArr = s.toCharArray();
char[] tArr = t.toCharArray();
int[] hash = new int[256];
// 值为字符出现的次数
for (int i = 0; i < tArr.length; ++i) {
hash[tArr[i]]++;
}
int left = 0;
int count = tArr.length;
int max = s.length();
String result = "";
for (int right = 0; right < sArr.length; right++) {
hash[sArr[right]]--;
// 存在s串的字符时
if (hash[sArr[right]] >= 0) {
count--;
}
// 重置起始节点
// 不存在或重复存在hash值此时都小于0
while (left < right && hash[sArr[left]] < 0) {
// 恢复之前检查存在减1
hash[sArr[left]]++;
left++;
}
// 匹配时长度缩小
if (count == 0 && max > right - left) {
max = right - left + 1;
result = s.substring(left, right + 1);
}
}
return result;
}
2、串排列是否为另一个子串
public static boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) {
return false;
}
char[] s1Arr = s1.toCharArray();
char[] s2Arr = s2.toCharArray();
int[] hash = new int[26];
for (int i = 0; i < s1Arr.length; ++i) {
hash[s1Arr[i] - 'a']++;
}
int left = 0;
int count = 0;
for (int right = 0; right < s2Arr.length; right++) {
hash[s1Arr[right]-'a']--;
if (hash[s1Arr[right]-'a'] >= 0){
count++;
}
// 加入长度限制, right-left+1 长度等于s1.length
if (right >= s1Arr.length){
hash[s2Arr[left]-'a']++;
if (hash[s2Arr[left]-'a'] >= 1){
count--;
}
left++;
}
if (count == s1Arr.length) {
return true;
}
}
return false;
}
3、无重复的最长子串
public static int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] sArr = s.toCharArray();
int[] hash = new int[256];
int l = 0;
int res = 1;
for (int r = 0; r < s.length(); r++) {
hash[sArr[r]]++;
while (hash[sArr[r]] != 1) {
hash[sArr[l]]--;
l++;
}
res = Math.max(res, r - l + 1);
}
return res;
}
4、查找字符串的所有异位词
private static List<Integer> findAnagrams(String s1, String s2) {
if (s1.length() < s2.length()){
return Collections.emptyList();
}
int[] hash = new int[26];
char[] s2Arr = s2.toCharArray();
for (int i = 0; i < s2.length(); i++) {
hash[s2Arr[i]-'a']++;
}
char[] s1Arr = s1.toCharArray();
int left = 0;
int count = 0;
List<Integer> res = new ArrayList<>();
for (int right = 0; right < s1.length(); right++) {
hash[s1Arr[right]-'a']--;
if (hash[s1Arr[right]-'a']>=0){
count++;
}
if (right > s2.length()-1){
hash[s1Arr[left]-'a']++;
if (hash[s1Arr[left]-'a']>0){
count--;
}
left++;
}
if (count == s2.length()){
res.add(left);
}
}
return res;
}
更多推荐


所有评论(0)