Skip to content

Commit 3589547

Browse files
committed
滑动窗口法
1 parent 7196d5c commit 3589547

File tree

6 files changed

+129
-113
lines changed

6 files changed

+129
-113
lines changed

question0003_longest_substring_without_repeating_characters/Solution2.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,18 @@
1111
*/
1212
public class Solution2 {
1313
public int lengthOfLongestSubstring(String s) {
14-
int n;
15-
if (null == s || (n = s.length()) == 0) {
16-
return 0;
17-
}
18-
boolean[] appear = new boolean[256];
19-
int left = 0, right = -1, result = 0; //滑动窗口范围是[left, right]
20-
while (right + 1 < n) {
21-
if (!appear[s.charAt(right + 1)]) {
22-
right++;
23-
appear[s.charAt(right)] = true;
24-
} else {
25-
appear[s.charAt(left)] = false; //因为滑动窗口中不可能包含重复字符,故去除left处的字符后,滑动窗口将不包含该字符
14+
int[] window = new int[256];
15+
int left = 0, right = 0, result = 0; //滑动窗口范围是[left, right)
16+
while (right < s.length()) {
17+
char cRight = s.charAt(right);
18+
right++;
19+
window[cRight]++;
20+
while (window[cRight] > 1) {
21+
char cLeft = s.charAt(left);
2622
left++;
23+
window[cLeft]--;
2724
}
28-
result = Math.max(result, right - left + 1);
25+
result = Math.max(result, right - left);
2926
}
3027
return result;
3128
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package question0076_minimum_window_substring;
2+
3+
/**
4+
* 滑动窗口法。
5+
*
6+
* 时间复杂度是O(n1 + n2),其中n1为字符串s的长度,n2为字符串t的长度。空间复杂度是O(1)。
7+
*
8+
* 执行用时:8ms,击败77.99%。消耗内存:40.1MB,击败13.33%。
9+
*/
10+
public class Solution {
11+
public String minWindow(String s, String t) {
12+
int[] window = new int[256], tMap = new int[256];
13+
for (int i = 0; i < t.length(); i++) {
14+
tMap[t.charAt(i)]++;
15+
}
16+
String result = s + "a";
17+
int left = 0, right = 0, need = t.length();
18+
while (right < s.length()) {
19+
char cRight = s.charAt(right);
20+
window[cRight]++;
21+
if (window[cRight] <= tMap[cRight]) {
22+
need--;
23+
}
24+
right++;
25+
while (need == 0) {
26+
if (right - left < result.length()) {
27+
result = s.substring(left, right);
28+
}
29+
char cLeft = s.charAt(left);
30+
window[cLeft] = window[cLeft] - 1;
31+
if (window[cLeft] < tMap[cLeft]) {
32+
need++;
33+
}
34+
left++;
35+
}
36+
}
37+
return result.length() == s.length() + 1 ? "" : result;
38+
}
39+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package question0438_find_all_anagrams_in_a_string;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* 滑动窗口法。
8+
*
9+
* 时间复杂度是O(n1 + n2),其中n1为字符串s的长度,n2为字符串p的长度。
10+
*
11+
* 执行用时:12ms,击败65.27%。消耗内存:41MB,击败5.88%。
12+
*/
13+
public class Solution {
14+
public List<Integer> findAnagrams(String s, String p) {
15+
int[] window = new int[26], pMap = new int[26];
16+
for (int i = 0; i < p.length(); i++) {
17+
pMap[p.charAt(i) - 'a']++;
18+
}
19+
int left = 0, right = 0, need = p.length();
20+
List<Integer> result = new ArrayList<>();
21+
while (right < s.length()) {
22+
char cRight = s.charAt(right);
23+
right++;
24+
window[cRight - 'a']++;
25+
if (window[cRight - 'a'] <= pMap[cRight - 'a']) {
26+
need--;
27+
}
28+
while (right - left > p.length()) {
29+
char cLeft = s.charAt(left);
30+
left++;
31+
window[cLeft - 'a']--;
32+
if (window[cLeft - 'a'] < pMap[cLeft - 'a']) {
33+
need++;
34+
}
35+
}
36+
if (right - left == p.length() && need == 0) {
37+
result.add(left);
38+
}
39+
}
40+
return result;
41+
}
42+
}

question0567/Solution.java

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package question0567_permutation_in_string;
2+
3+
/**
4+
* 滑动窗口法。
5+
*
6+
* 时间复杂度是O(n1 + n2),其中n1为字符串s1的长度,n2为字符串s2的长度。空间复杂度是O(1)。
7+
*
8+
* 执行用时:10ms,击败57.67%。消耗内存:39.6MB,击败18.75%。
9+
*/
10+
public class Solution {
11+
public boolean checkInclusion(String s1, String s2) {
12+
int[] window = new int[26], s1Map = new int[26];
13+
for (int i = 0; i < s1.length(); i++) {
14+
s1Map[s1.charAt(i) - 'a']++;
15+
}
16+
int left = 0, right = 0, need = s1.length();
17+
while (right < s2.length()) {
18+
char cRight = s2.charAt(right);
19+
window[cRight - 'a']++;
20+
if (window[cRight - 'a'] <= s1Map[cRight - 'a']) {
21+
need--;
22+
}
23+
right++;
24+
while (right - left > s1.length()) {
25+
char cLeft = s2.charAt(left);
26+
left++;
27+
window[cLeft - 'a']--;
28+
if (window[cLeft - 'a'] < s1Map[cLeft - 'a']) {
29+
need++;
30+
}
31+
}
32+
if (right - left == s1.length() && need == 0) {
33+
return true;
34+
}
35+
}
36+
return false;
37+
}
38+
}

question076/Solution.java

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)