slidingwindow
- Helps us avoid duplicating work when dealing with contigous elements (subarrays, etc)
end - start + 1is our window size
Fixed size window
start = end = 0
while(end < arraylength){
// include window end
if(window is valid){
// perform calculations
// move window start appropriately
}
}
2379. Minimum Recolors to Get K Consecutive Black Blocks
Input: blocks = "WBBWWBBWBW", k = 7
Output: 3
Explanation:
One way to achieve 7 consecutive black blocks is to recolor the 0th, 3rd, and 4th blocks
so that blocks = "BBBBBBBWBW".
It can be shown that there is no way to achieve 7 consecutive black blocks in less than 3 operations.
Therefore, we return 3.
public int minimumRecolors(String blocks, int k) {
int count = 0, min = Integer.MAX_VALUE, i = 0;
for(int j = 0; j < blocks.length(); j++){
if(blocks.charAt(j) == 'W') count++;
// valid window
if(j - i + 1 == k){
min = Math.min(min, count);
if(blocks.charAt(i++) == 'W') count--;
}
}
return min;
}
1343. Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold
Given an array of integers arr and two integers k and threshold, return the number of sub-arrays of size k and average greater than or equal to threshold.
Input: arr = [2,2,2,2,5,5,5,8], k = 3, threshold = 4
Output: 3
Explanation: Sub-arrays [2,5,5],[5,5,5] and [5,5,8] have averages 4, 5 and 6 respectively.
All other sub-arrays of size 3 have averages less than 4 (the threshold).
public int numOfSubarrays(int[] arr, int k, int threshold) {
int sum = 0, count = 0, m = threshold * k;
for(int i = 0; i < arr.length; i++){
sum += arr[i]; // expand window
// do calculations if window size has reached K
if(i + 1 >= k){
if(sum >= m) count++;
sum -= arr[i - k + 1];
}
}
return count;
}
Dynamic size window
start = end = 0
while(end < arraylength){
// include window end
// window shrink
// we can choose to shrink the window multiple times or ONCE
while or IF(can shrink){
// perform calculations
// move window start appropriately
}
}
Caterpillar-style movement
- We can shrink window one or more times based on some conditions while end is stationery
1004. Max Consecutive Ones III
Given a binary array nums and an integer k, return the maximum number of consecutive 1's in the array if you can flip at most k 0's.
Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
Output: 6
Explanation: [1,1,1,0,0,1,1,1,1,1,1]
class Solution {
public int longestOnes(int[] nums, int k) {
// make note of zeros
// if zeros > k, shrink window once
// we can replace the WHILE condition to shrink window with IF,
// and it works just fine
int i = 0, zeros = 0, ans = -1;
for(int j = 0; j < nums.length; j++){
zeros += (nums[j] ^ 1);
if(zeros > k) zeros -= (nums[i++] ^ 1);
ans = Math.max(ans, j - i + 1);
}
return ans;
}
}
76. Minimum Window Substring (Hard)
Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
- Create a variable
matchesthat count how many of the chars in stringtis in our window - window =
BBACB, t =ABC matches = 3as extra freqs are not counted in matches (but freqs are still noted elsewhere for later use)
public String minWindow(String s, String t) {
int m = s.length(), n = t.length();
int[] tfreq = new int[128];
for (int i = 0; i < n; i++) ++tfreq[t.charAt(i)];
int[] window = new int[128];
int matches = 0, min = Integer.MAX_VALUE, i = 0, ans = 0;
for (int j = 0; j < m; j++) {
// increase matches only if window has freq atmost equal to freq in t
char rightChar = s.charAt(j);
if (++window[rightChar] <= tfreq[rightChar])
++matches;
// Shrink window
while (matches == n) {
if (j - i + 1 < min) {
min = j - i + 1;
ans = i;
}
// reduce matches if moving i causes our window to not have t
// stops shrinking as window doesn't contain t now
char leftChar = s.charAt(i++);
if (--window[leftChar] < tfreq[leftChar])
--matches;
}
}
return min == Integer.MAX_VALUE ? "" : s.substring(ans, ans + min);
}
Starting a new window (or Resetting count)
- This is useful for when we want to track longest consecutive-style problems
- Incresae count if sequence is continued
- Reset if sequence is broken
485. Max Consecutive Ones
Given a binary array nums, return the maximum number of consecutive 1's in the array.
Input: nums = [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
The maximum number of consecutive 1s is 3.
public int findMaxConsecutiveOnes(int[] nums) {
int max = 0, count = 0;
for(int i: nums){
if(i == 0) count = 0; // reset count
else max = Math.max(max, ++count);
}
return max;
}
2414. Length of the Longest Alphabetical Continuous Substring
Input: s = "abacaba"
Output: 2
Explanation: There are 4 distinct continuous substrings: "a", "b", "c" and "ab".
"ab" is the longest continuous substring.
public int longestContinuousSubstring(String s) {
int count = 1, max = 1, prev = s.charAt(0);
for(int i = 1; i < s.length(); i++){
// increase count if curr char is prev + 1
char c = s.charAt(i);
if(prev + 1 == c) max = Math.max(max, ++count);
else count = 1;
prev = c;
}
return max;
}