Intro
Sliding Window for Substring problem Template:
https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92007/Sliding-Window-algorithm-template-to-solve-all-the-Leetcode-substring-search-problem.
1 | def slidingWindow(s, p): |
Substring problem
438. Find All Anagrams in a String
Leetcode: https://leetcode.com/problems/find-all-anagrams-in-a-string/
1 | def findAnagrams(self, s: str, p: str) -> List[int]: |
340. Longest Substring with At Most K Distinct Characters
Leetcode: https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/
1 | def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int: |
76. Minimum Window Substring
Leetcode: https://leetcode.com/problems/minimum-window-substring/description/
Solution: https://www.youtube.com/watch?v=9qFR2WQGqkU
1 | find A B C |
matchCount
: record how many keys in wordDict are FULLY matchedminLength
: record the minimum length of matched Substringindex
: record the head index of the minimum substring
- Use slow and fast two pointers to update window
- Construct a wordDict with HashMap
- Forward the fast pointer to check if any character belongs to the dict keys
char ch = s.charAt(fast)
check if the Character at fast is in thewordDict
- if not: forward
- if in the
wordDict
, update thewordDict
count (needMatch - 1), updatematchCount++
- While all characters in
wordDict
are matched:- find the valid substring, record index, minLength
- move slow pointer to left, check the leftmost character
- if leftmost character not in the
wordDict
, doesn’t matter, move forward - else if leftmost character in the
wordDict
, update thewordDict
count (needMatch + 1) - if leftmost character has increased from 0 to 1 in
wordDict
, which means matched character reduced by 1matchCount--
- if minLength is still Integer.MAX_VALUE: not matched: return “”, else return
s.substring(index, index + minLength)
[Caption]:
how to construct map wordDict function
1 | private Map<Character, Integer> constructWordDict(String t) { |
3. Longest Substring Without Repeating Characters[M]
Leetcode: https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
Solution
- Use a
HashSet
to store unique values - Use the window problem template
- Solution: https://leetcode.com/articles/longest-substring-without-repeating-characters/
1 | const lengthOfLongestSubstringTwoDistinct = (s) => { |
1 | def lengthOfLongestSubstring(self, s: str) -> int: |
159. Longest Substring with At Most Two Distinct Characters
Leetcode: https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/description/
Solution
- Use
Hashtable
to keep track of counts of characters - Use the window problem template
1 | def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int: |
30. Substring with Concatenation of All Words
Leetcode: https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/
Solution: https://www.youtube.com/watch?v=L6NLra-rZoU
(The description of this problem is not consistent with its test cases in terms of if the words’ length are the same. This solution is based on the assumption that all words’ lengths are the same)
1 | find ["foo","bar"] |
fast
: fast pointerslow
: slow pointermatchCount
: how many string items left to be matchedheads
: keep track of the headsstep
: word lengthwordDict
: Map that keep track of how many words left to be matched
Solution
- Get the wordDict
- Forward the fast pointer at a pace of
step
- If word at the fast pointer not match in the wordDict
- Discard all the steps and restore wordDict and matchCount, continue
- Else if the word matched in the wordDict
- update the wordDict value
- If the word is fully matched, matchCount++
- If all words are fully matched
- record slow index in the heads
- move forward slow index
- Restore wordDict and matchCount, continue
- If word at the fast pointer not match in the wordDict
904. Fruit Into Baskets
Leetcode: https://leetcode.com/problems/fruit-into-baskets/
1 | def totalFruit(self, tree): |
Subarray Problems
209. Minimum Size Subarray Sum
Leetcode: https://leetcode.com/problems/minimum-size-subarray-sum/description/
Window problem template:
1 | While(tail < nums.length): |
Note:
- Remember to return 0 when no reslut found
1 | def minSubArrayLen(self, s: int, nums: List[int]) -> int: |
Binary Search Approach: Ologn
1 | def minSubArrayLen(self, s: int, nums: List[int]) -> int: |
713. Subarray Product Less Than K
Leetcode: https://leetcode.com/problems/subarray-product-less-than-k/
Note:
- The condition for the
while loop
isl <= r
, if num itself is larger than the target, thenl = r + 1
, thencnt
will be added0
. For every new number
r
introduces, the count will increaser - l + 1
for window (5, 2), when 6 is introduced, it add 3 new subarray:1
2
3(6)
(2,6)
(5,2,6)Use
l <= r
rather thanl < r
since we can count one element as a single subarray
1 | def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int: |
992. Subarrays with K Different Integers
Leetcode: https://leetcode.com/problems/subarrays-with-k-different-integers/
Note:
- Number of subarrays With exact K = Number of subarrays with at most K - Number of subarrays with at most K - 1
- For each new element
r
introduces, we increasel - r + 1
.1
2
3
41, 2, 2 is valid, we introduce 2
1, 2, 2, 2
2, 2, 2
2, 2 will all be valid since it's AT MOST K, not exact K
1 | def subarraysWithKDistinct(self, A: List[int], K: int) -> int: |
487. Max Consecutive Ones II
Leetcode: https://leetcode.com/problems/max-consecutive-ones-ii/
Note:
Set a zero
value for 0
, once it’s below 1
, we move l
pointer forward.
1 | def findMaxConsecutiveOnes(self, nums: List[int]) -> int: |
1004. Max Consecutive Ones III
Leetcode: https://leetcode.com/problems/max-consecutive-ones-iii/
Note: Same as the problem above.
1 | def longestOnes(self, A: List[int], K: int) -> int: |