Algorithms
Sliding Window
The Sliding Window algorithm helps you find a property of a substring, subarray or some window within a larger sequential list.
There are two variations of this approach: Fixed Sliding Window, where the window size is static, and Dynamic Sliding Window where the window size can increase and decrease based on some criteria.
It’s O(n) time where n is the size of the list.
Example Problems
Problem prompt
Given a string s
, find the length of the longest substring without duplicate characters.
Example 1
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke"
, with the length of 3
.
Notice that the answer must be a substring, "pwke"
is a subsequence and not a substring.
Solution This problem can be solved using a dynamic sliding window approach.
Before we throw the algorithm at it, we need a basic sanity check to see if the input s
is empty, in which
case we should just return 0
:
if len(s) == 0 {
return 0
}
We’ll need a set (in Go, use map[byte]bool
) to store the set of unique characters in our current window:
set := map[byte]bool
Our window will start out empty. We’ll use an index l
as a pointer to the beginning of our window, and r
to denote the end
of our window. We can initialize these both to 0
:
l, r := 0, 0
We’ll also need a longest
variable to track the longest length of window we’ve seen so far:
longest := 0
We’ll want to process the input string s
while the right pointer is within the string length:
for r < len(s) {
// Advance/adjust our sliding window
}
Every iteration we’ll see if we can "take" the next character (s[r]
) or not. We can take it if it’s not already in our
set, otherwise, we’ll have to adjust our sliding window:
if (!set[s[r]]) {
// take the current character, and advance to next character
set[s[r]] = true
r++
} else {
// can't take current character, so trim the left character off our sliding window
// (shrink window from the left)
delete(set[s[l]])
l++
}
Putting the whole solution together:
func lengthOfLongestSubstring(s string) int {
longest := 0
l, r := 0, 0
set := map[byte]bool{}
if len(s) == 0 {
return 0
}
for r < len(s) {
if (!set[s[r]]) {
set[s[r]] = true
r++
} else {
delete(set, s[l])
l++
}
// Update longest seen substring length
if len(set) > longest {
longest = len(set)
}
}
return longest
}