Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 062d4fc

Browse files
committed
Sliding Window Problems: done
1 parent 1eafcd9 commit 062d4fc

File tree

8 files changed

+252
-15
lines changed

8 files changed

+252
-15
lines changed

‎src/main/java/com/leetcode/arrays/ShortestWordDistance.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.leetcode.arrays;
22

3+
import com.leetcode.hashtables.ShortestWordDistanceII;
4+
35
import static org.junit.jupiter.api.Assertions.assertEquals;
46

57
/**
@@ -16,7 +18,7 @@
1618
*
1719
* Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list.
1820
*
19-
* Lastly, for a more complex variant, see {@link com.leetcode.maps.ShortestWordDistanceII}.
21+
* Lastly, for a more complex variant, see {@link ShortestWordDistanceII}.
2022
*
2123
* @author rampatra
2224
* @since 2019年07月31日

‎src/main/java/com/leetcode/maps/IsomorphicStrings.java renamed to ‎src/main/java/com/leetcode/hashtables/IsomorphicStrings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.leetcode.maps;
1+
package com.leetcode.hashtables;
22

33
import java.util.HashMap;
44
import java.util.Map;

‎src/main/java/com/leetcode/maps/RepeatedDnaSequence.java renamed to ‎src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.leetcode.maps;
1+
package com.leetcode.hashtables;
22

33
import java.util.*;
44

‎src/main/java/com/leetcode/maps/ShortestWordDistanceII.java renamed to ‎src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.leetcode.maps;
1+
package com.leetcode.hashtables;
22

33
import java.util.ArrayList;
44
import java.util.HashMap;

‎src/main/java/com/leetcode/maps/TwoSumIII.java renamed to ‎src/main/java/com/leetcode/hashtables/TwoSumIII.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.leetcode.maps;
1+
package com.leetcode.hashtables;
22

33
import java.util.HashMap;
44
import java.util.Map;

‎src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java renamed to ‎src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.leetcode.maps.slidingwindow;
1+
package com.leetcode.hashtables.slidingwindow;
22

33
import java.util.HashMap;
44
import java.util.Map;
@@ -38,11 +38,11 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) {
3838
int length = 0;
3939
Map<Character, Integer> letterCountInWindow = new HashMap<>();
4040

41-
int i = 0; // start of window
42-
int j = i; // end of window
41+
int left = 0; // start of window
42+
int right = 0; // end of window
4343

44-
while (j < str.length()) {
45-
char ch = str.charAt(j);
44+
while (right < str.length()) {
45+
char ch = str.charAt(right);
4646

4747
letterCountInWindow.put(ch, letterCountInWindow.getOrDefault(ch, 0) + 1);
4848

@@ -51,20 +51,20 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) {
5151
// - remove the first character in the window or reduce its count if the window had more than one of this character
5252
// - lastly, move the window forward
5353
if (letterCountInWindow.keySet().size() > k) {
54-
char firstChar = str.charAt(i);
54+
char firstChar = str.charAt(left);
5555
int firstCharCount = letterCountInWindow.get(firstChar);
5656
if (firstCharCount > 1) {
5757
letterCountInWindow.put(firstChar, firstCharCount - 1);
5858
} else {
5959
letterCountInWindow.remove(firstChar);
6060
}
61-
length = Math.max(length, j - i);
62-
i++;
61+
length = Math.max(length, right - left);
62+
left++;
6363
}
64-
j++;
64+
right++;
6565
}
6666

67-
return length == 0 ? j - i : length;
67+
return length == 0 ? right - left : length;
6868
}
6969

7070
public static void main(String[] args) {
@@ -75,5 +75,8 @@ public static void main(String[] args) {
7575
assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1));
7676
assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1));
7777
assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0));
78+
assertEquals(3, lengthOfLongestSubstringKDistinct("aab", 2));
79+
assertEquals(8, lengthOfLongestSubstringKDistinct("abcabcbb", 3));
80+
assertEquals(5, lengthOfLongestSubstringKDistinct("pwwkew", 3));
7881
}
7982
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.leetcode.hashtables.slidingwindow;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
import static org.junit.jupiter.api.Assertions.assertEquals;
7+
8+
/**
9+
* Level: Medium
10+
* Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/
11+
* Description:
12+
* Given a string, find the length of the longest substring without repeating characters.
13+
* <p>
14+
* Example 1:
15+
* Input: "abcabcbb"
16+
* Output: 3
17+
* Explanation: The answer is "abc", with the length of 3.
18+
* <p>
19+
* Example 2:
20+
* Input: "bbbbb"
21+
* Output: 1
22+
* Explanation: The answer is "b", with the length of 1.
23+
* <p>
24+
* Example 3:
25+
* Input: "pwwkew"
26+
* Output: 3
27+
* Explanation: The answer is "wke", with the length of 3.
28+
* Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
29+
*
30+
* @author rampatra
31+
* @since 2019年08月15日
32+
*/
33+
public class LongestSubstringWithoutRepeatingCharacters {
34+
35+
/**
36+
* Sliding Window Approach (using map).
37+
* <p>
38+
* Note:
39+
* If we know that the charset is rather small, we can replace the Map with an integer array as direct access table.
40+
* <p>
41+
* Commonly used tables are:
42+
* <p>
43+
* int[26] for Letters 'a' - 'z' or 'A' - 'Z'
44+
* int[128] for ASCII
45+
* int[256] for Extended ASCII
46+
* <p>
47+
* Runtime: <a href="https://leetcode.com/submissions/detail/251869571/">8 ms</a>.
48+
*
49+
* @param s
50+
* @return
51+
*/
52+
public static int lengthOfLongestSubstring(String s) {
53+
int left = 0;
54+
int right = 0;
55+
int longestSubstringLen = 0;
56+
Set<Character> charsInWindow = new HashSet<>();
57+
58+
59+
while (right < s.length()) {
60+
61+
if (charsInWindow.contains(s.charAt(right))) {
62+
while (s.charAt(left) != s.charAt(right)) {
63+
longestSubstringLen = Math.max(longestSubstringLen, right - left);
64+
charsInWindow.remove(s.charAt(left));
65+
left++;
66+
}
67+
left++;
68+
}
69+
70+
charsInWindow.add(s.charAt(right));
71+
right++;
72+
}
73+
74+
return Math.max(longestSubstringLen, right - left);
75+
}
76+
77+
/**
78+
* Sliding Window Approach using int array.
79+
*
80+
* Runtime: <a href="https://leetcode.com/submissions/detail/251869406/">2 ms</a>.
81+
*
82+
* @param s
83+
* @return
84+
*/
85+
public static int lengthOfLongestSubstringNoMap(String s) {
86+
int left = 0;
87+
int right = 0;
88+
int longestSubstringLen = 0;
89+
int[] charsInWindow = new int[128];
90+
91+
// keep moving forward the right pointer and adding characters to the window
92+
while (right < s.length()) {
93+
94+
// once we encounter repeated characters, move the left pointer until the repeated character is removed
95+
if (charsInWindow[s.charAt(right)] == 1) {
96+
while (s.charAt(left) != s.charAt(right)) {
97+
longestSubstringLen = Math.max(longestSubstringLen, right - left);
98+
charsInWindow[s.charAt(left)] = 0;
99+
left++;
100+
}
101+
left++;
102+
}
103+
104+
charsInWindow[s.charAt(right)] = 1;
105+
right++;
106+
}
107+
108+
return Math.max(longestSubstringLen, right - left);
109+
}
110+
111+
public static void main(String[] args) {
112+
assertEquals(0, lengthOfLongestSubstring(""));
113+
assertEquals(1, lengthOfLongestSubstring(" "));
114+
assertEquals(1, lengthOfLongestSubstring("a"));
115+
assertEquals(2, lengthOfLongestSubstring("aab"));
116+
assertEquals(3, lengthOfLongestSubstring("abcabcbb"));
117+
assertEquals(1, lengthOfLongestSubstring("bbbbb"));
118+
assertEquals(3, lengthOfLongestSubstring("pwwkew"));
119+
120+
assertEquals(0, lengthOfLongestSubstringNoMap(""));
121+
assertEquals(1, lengthOfLongestSubstringNoMap(" "));
122+
assertEquals(1, lengthOfLongestSubstringNoMap("a"));
123+
assertEquals(2, lengthOfLongestSubstringNoMap("aab"));
124+
assertEquals(3, lengthOfLongestSubstringNoMap("abcabcbb"));
125+
assertEquals(1, lengthOfLongestSubstringNoMap("bbbbb"));
126+
assertEquals(3, lengthOfLongestSubstringNoMap("pwwkew"));
127+
}
128+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.leetcode.hashtables.slidingwindow;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import static org.junit.jupiter.api.Assertions.assertEquals;
7+
8+
/**
9+
* Level: Hard
10+
* Link: https://leetcode.com/problems/minimum-window-substring/
11+
* Description:
12+
* Given a string S and a string T, find the minimum window in S which will contain all the characters in T in
13+
* complexity O(n).
14+
* <p>
15+
* Example:
16+
* <p>
17+
* Input: S = "ADOBECODEBANC", T = "ABC"
18+
* Output: "BANC"
19+
* <p>
20+
* Note:
21+
* - If there is no such window in S that covers all characters in T, return the empty string "".
22+
* - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
23+
*
24+
* @author rampatra
25+
* @since 2019年08月13日
26+
*/
27+
public class MinimumWindowSubstring {
28+
29+
/**
30+
* Sliding Window Approach (using map).
31+
*
32+
* Note:
33+
* If we know that the charset is rather small, we can replace the Map with an integer array as direct access table.
34+
*
35+
* Commonly used tables are:
36+
*
37+
* int[26] for Letters 'a' - 'z' or 'A' - 'Z'
38+
* int[128] for ASCII
39+
* int[256] for Extended ASCII
40+
*
41+
* Runtime: <a href="https://leetcode.com/submissions/detail/251862380/">22 ms</a>.
42+
*
43+
* @param s
44+
* @param t
45+
* @return
46+
*/
47+
public static String minWindow(String s, String t) {
48+
49+
int left = 0; // start of window
50+
int right = 0; // end of window
51+
int begin = 0;
52+
int windowSize = Integer.MAX_VALUE;
53+
int charsInWindow = 0; // to check whether the window has all the characters in t with the required frequency
54+
55+
// characters and their counts in t
56+
Map<Character, Integer> dictT = new HashMap<>();
57+
for (int i = 0; i < t.length(); i++) {
58+
char ch = t.charAt(i);
59+
dictT.put(ch, dictT.getOrDefault(ch, 0) + 1);
60+
}
61+
62+
// characters and their counts in the window
63+
Map<Character, Integer> dictWindow = new HashMap<>();
64+
65+
while (right < s.length()) {
66+
char rightChar = s.charAt(right);
67+
int rightCharCount;
68+
dictWindow.put(rightChar, (rightCharCount = dictWindow.getOrDefault(rightChar, 0) + 1));
69+
70+
// once the window has a character in t with the required frequency, increment charsInWindow
71+
if (dictT.get(rightChar) != null && dictT.get(rightChar).equals(rightCharCount)) {
72+
charsInWindow++;
73+
}
74+
75+
// once the window has all characters in t with required frequency then shorten the window by moving the
76+
// left window forward until the window no longer has all characters of t
77+
while (left <= right && charsInWindow == dictT.size()) {
78+
if (right - left < windowSize) {
79+
windowSize = right - left + 1;
80+
begin = left;
81+
}
82+
83+
char leftChar = s.charAt(left);
84+
Integer leftCharCount = dictWindow.get(leftChar);
85+
dictWindow.put(leftChar, leftCharCount - 1);
86+
87+
if (dictT.get(leftChar) != null && leftCharCount - 1 < dictT.get(leftChar)) {
88+
charsInWindow--;
89+
}
90+
left++;
91+
}
92+
right++;
93+
}
94+
95+
return windowSize == Integer.MAX_VALUE ? "" : s.substring(begin, begin + windowSize);
96+
}
97+
98+
public static void main(String[] args) {
99+
assertEquals("BANC", minWindow("ADOBECODEBANC", "ABC"));
100+
assertEquals("BAC", minWindow("ADOBECODEBAC", "ABC"));
101+
assertEquals("ba", minWindow("bba", "ab"));
102+
assertEquals("baca", minWindow("acbbaca", "aba"));
103+
}
104+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /