|
| 1 | +# Sliding Window Technique |
| 2 | + |
| 3 | +The sliding window technique is a fundamental approach used to solve problems involving arrays, lists, or sequences. It's particularly useful when you need to calculate something over a subarray or sublist of fixed size that slides over the entire array. |
| 4 | + |
| 5 | +In easy words, It is the transformation of the nested loops into the single loop |
| 6 | +## Concept |
| 7 | + |
| 8 | +The sliding window technique involves creating a window (a subarray or sublist) that moves or "slides" across the entire array. This window can either be fixed in size or dynamically resized. By maintaining and updating this window as it moves, you can optimize certain computations, reducing time complexity. |
| 9 | + |
| 10 | +## Types of Sliding Windows |
| 11 | + |
| 12 | +1. **Fixed Size Window**: The window size remains constant as it slides from the start to the end of the array. |
| 13 | +2. **Variable Size Window**: The window size can change based on certain conditions, such as the sum of elements within the window meeting a specified target. |
| 14 | + |
| 15 | +## Steps to Implement a Sliding Window |
| 16 | + |
| 17 | +1. **Initialize the Window**: Set the initial position of the window and any required variables (like sum, count, etc.). |
| 18 | +2. **Expand the Window**: Add the next element to the window and update the relevant variables. |
| 19 | +3. **Shrink the Window**: If needed, remove elements from the start of the window and update the variables. |
| 20 | +4. **Slide the Window**: Move the window one position to the right by including the next element and possibly excluding the first element. |
| 21 | +5. **Repeat**: Continue expanding, shrinking, and sliding the window until you reach the end of the array. |
| 22 | + |
| 23 | +## Example Problems |
| 24 | + |
| 25 | +### 1. Maximum Sum Subarray of Fixed Size K |
| 26 | + |
| 27 | +Given an array of integers and an integer k, find the maximum sum of a subarray of size k. |
| 28 | + |
| 29 | +**Steps:** |
| 30 | + |
| 31 | +1. Initialize the sum of the first k elements. |
| 32 | +2. Slide the window from the start of the array to the end, updating the sum by subtracting the element that is left behind and adding the new element. |
| 33 | +3. Track the maximum sum encountered. |
| 34 | + |
| 35 | +**Python Code:** |
| 36 | + |
| 37 | +```python |
| 38 | +def max_sum_subarray(arr, k): |
| 39 | + n = len(arr) |
| 40 | + if n < k: |
| 41 | + return None |
| 42 | + |
| 43 | + # Compute the sum of the first window |
| 44 | + window_sum = sum(arr[:k]) |
| 45 | + max_sum = window_sum |
| 46 | + |
| 47 | + # Slide the window from start to end |
| 48 | + for i in range(n - k): |
| 49 | + window_sum = window_sum - arr[i] + arr[i + k] |
| 50 | + max_sum = max(max_sum, window_sum) |
| 51 | + |
| 52 | + return max_sum |
| 53 | + |
| 54 | +# Example usage: |
| 55 | +arr = [1, 3, 2, 5, 1, 1, 6, 2, 8, 5] |
| 56 | +k = 3 |
| 57 | +print(max_sum_subarray(arr, k)) # Output: 16 |
| 58 | +``` |
| 59 | + |
| 60 | +### 2. Longest Substring Without Repeating Characters |
| 61 | + |
| 62 | +Given a string, find the length of the longest substring without repeating characters. |
| 63 | + |
| 64 | +**Steps:** |
| 65 | + |
| 66 | +1. Use two pointers to represent the current window. |
| 67 | +2. Use a set to track characters in the current window. |
| 68 | +3. Expand the window by moving the right pointer. |
| 69 | +4. If a duplicate character is found, shrink the window by moving the left pointer until the duplicate is removed. |
| 70 | + |
| 71 | +**Python Code:** |
| 72 | + |
| 73 | +```python |
| 74 | +def longest_unique_substring(s): |
| 75 | + n = len(s) |
| 76 | + char_set = set() |
| 77 | + left = 0 |
| 78 | + max_length = 0 |
| 79 | + |
| 80 | + for right in range(n): |
| 81 | + while s[right] in char_set: |
| 82 | + char_set.remove(s[left]) |
| 83 | + left += 1 |
| 84 | + char_set.add(s[right]) |
| 85 | + max_length = max(max_length, right - left + 1) |
| 86 | + |
| 87 | + return max_length |
| 88 | + |
| 89 | +# Example usage: |
| 90 | +s = "abcabcbb" |
| 91 | +print(longest_unique_substring(s)) # Output: 3 |
| 92 | +``` |
| 93 | +## 3. Minimum Size Subarray Sum |
| 94 | + |
| 95 | +Given an array of positive integers and a positive integer `s`, find the minimal length of a contiguous subarray of which the sum is at least `s`. If there isn't one, return 0 instead. |
| 96 | + |
| 97 | +### Steps: |
| 98 | +1. Use two pointers, `left` and `right`, to define the current window. |
| 99 | +2. Expand the window by moving `right` and adding `arr[right]` to `current_sum`. |
| 100 | +3. If `current_sum` is greater than or equal to `s`, update `min_length` and shrink the window from the left by moving `left` and subtracting `arr[left]` from `current_sum`. |
| 101 | +4. Repeat until `right` has traversed the array. |
| 102 | + |
| 103 | +### Python Code: |
| 104 | +```python |
| 105 | +def min_subarray_len(s, arr): |
| 106 | + n = len(arr) |
| 107 | + left = 0 |
| 108 | + current_sum = 0 |
| 109 | + min_length = float('inf') |
| 110 | + |
| 111 | + for right in range(n): |
| 112 | + current_sum += arr[right] |
| 113 | + |
| 114 | + while current_sum >= s: |
| 115 | + min_length = min(min_length, right - left + 1) |
| 116 | + current_sum -= arr[left] |
| 117 | + left += 1 |
| 118 | + |
| 119 | + return min_length if min_length != float('inf') else 0 |
| 120 | + |
| 121 | +# Example usage: |
| 122 | +arr = [2, 3, 1, 2, 4, 3] |
| 123 | +s = 7 |
| 124 | +print(min_subarray_len(s, arr)) # Output: 2 (subarray [4, 3]) |
| 125 | +``` |
| 126 | + |
| 127 | +## 4. Longest Substring with At Most K Distinct Characters |
| 128 | + |
| 129 | +Given a string `s` and an integer `k`, find the length of the longest substring that contains at most `k` distinct characters. |
| 130 | + |
| 131 | +### Steps: |
| 132 | +1. Use two pointers, `left` and `right`, to define the current window. |
| 133 | +2. Use a dictionary `char_count` to count characters in the window. |
| 134 | +3. Expand the window by moving `right` and updating `char_count`. |
| 135 | +4. If `char_count` has more than `k` distinct characters, shrink the window from the left by moving `left` and updating `char_count`. |
| 136 | +5. Keep track of the maximum length of the window with at most `k` distinct characters. |
| 137 | + |
| 138 | +### Python Code: |
| 139 | +```python |
| 140 | +def longest_substring_k_distinct(s, k): |
| 141 | + n = len(s) |
| 142 | + char_count = {} |
| 143 | + left = 0 |
| 144 | + max_length = 0 |
| 145 | + |
| 146 | + for right in range(n): |
| 147 | + char_count[s[right]] = char_count.get(s[right], 0) + 1 |
| 148 | + |
| 149 | + while len(char_count) > k: |
| 150 | + char_count[s[left]] -= 1 |
| 151 | + if char_count[s[left]] == 0: |
| 152 | + del char_count[s[left]] |
| 153 | + left += 1 |
| 154 | + |
| 155 | + max_length = max(max_length, right - left + 1) |
| 156 | + |
| 157 | + return max_length |
| 158 | + |
| 159 | +# Example usage: |
| 160 | +s = "eceba" |
| 161 | +k = 2 |
| 162 | +print(longest_substring_k_distinct(s, k)) # Output: 3 (substring "ece") |
| 163 | +``` |
| 164 | + |
| 165 | +## 5. Maximum Number of Vowels in a Substring of Given Length |
| 166 | + |
| 167 | +Given a string `s` and an integer `k`, return the maximum number of vowel letters in any substring of `s` with length `k`. |
| 168 | + |
| 169 | +### Steps: |
| 170 | +1. Use a sliding window of size `k`. |
| 171 | +2. Keep track of the number of vowels in the current window. |
| 172 | +3. Expand the window by adding the next character and update the count if it's a vowel. |
| 173 | +4. If the window size exceeds `k`, remove the leftmost character and update the count if it's a vowel. |
| 174 | +5. Track the maximum number of vowels found in any window of size `k`. |
| 175 | + |
| 176 | +### Python Code: |
| 177 | +```python |
| 178 | +def max_vowels(s, k): |
| 179 | + vowels = set('aeiou') |
| 180 | + max_vowel_count = 0 |
| 181 | + current_vowel_count = 0 |
| 182 | + |
| 183 | + for i in range(len(s)): |
| 184 | + if s[i] in vowels: |
| 185 | + current_vowel_count += 1 |
| 186 | + if i >= k: |
| 187 | + if s[i - k] in vowels: |
| 188 | + current_vowel_count -= 1 |
| 189 | + max_vowel_count = max(max_vowel_count, current_vowel_count) |
| 190 | + |
| 191 | + return max_vowel_count |
| 192 | + |
| 193 | +# Example usage: |
| 194 | +s = "abciiidef" |
| 195 | +k = 3 |
| 196 | +print(max_vowels(s, k)) # Output: 3 (substring "iii") |
| 197 | +``` |
| 198 | + |
| 199 | +## 6. Subarray Product Less Than K |
| 200 | + |
| 201 | +Given an array of positive integers `nums` and an integer `k`, return the number of contiguous subarrays where the product of all the elements in the subarray is less than `k`. |
| 202 | + |
| 203 | +### Steps: |
| 204 | +1. Use two pointers, `left` and `right`, to define the current window. |
| 205 | +2. Expand the window by moving `right` and multiplying `product` by `nums[right]`. |
| 206 | +3. If `product` is greater than or equal to `k`, shrink the window from the left by moving `left` and dividing `product` by `nums[left]`. |
| 207 | +4. For each position of `right`, the number of valid subarray ending at `right` is `right - left + 1`. |
| 208 | +5. Sum these counts to get the total number of subarray with product less than `k`. |
| 209 | + |
| 210 | +### Python Code: |
| 211 | +```python |
| 212 | +def num_subarray_product_less_than_k(nums, k): |
| 213 | + if k <= 1: |
| 214 | + return 0 |
| 215 | + |
| 216 | + product = 1 |
| 217 | + left = 0 |
| 218 | + count = 0 |
| 219 | + |
| 220 | + for right in range(len(nums)): |
| 221 | + product *= nums[right] |
| 222 | + |
| 223 | + while product >= k: |
| 224 | + product /= nums[left] |
| 225 | + left += 1 |
| 226 | + |
| 227 | + count += right - left + 1 |
| 228 | + |
| 229 | + return count |
| 230 | + |
| 231 | +# Example usage: |
| 232 | +nums = [10, 5, 2, 6] |
| 233 | +k = 100 |
| 234 | +print(num_subarray_product_less_than_k(nums, k)) # Output: 8 |
| 235 | +``` |
| 236 | + |
| 237 | +## Advantages |
| 238 | + |
| 239 | +- **Efficiency**: Reduces the time complexity from O(n^2) to O(n) for many problems. |
| 240 | +- **Simplicity**: Provides a straightforward way to manage subarrays/substrings with overlapping elements. |
| 241 | + |
| 242 | +## Applications |
| 243 | + |
| 244 | +- Finding the maximum or minimum sum of subarrays of fixed size. |
| 245 | +- Detecting unique elements in a sequence. |
| 246 | +- Solving problems related to dynamic programming with fixed constraints. |
| 247 | +- Efficiently managing and processing streaming data or real-time analytics. |
| 248 | + |
| 249 | +By using the sliding window technique, you can tackle a wide range of problems in a more efficient manner. |
0 commit comments