Skip to content

Commit ac2ba66

Browse files
committed
Two-Hundred-Sixty-Four Commit: Amend Sliding_Window_Tutorial.txt in Sliding Window section
1 parent 3fa9211 commit ac2ba66

File tree

2 files changed

+293
-45
lines changed

2 files changed

+293
-45
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
Sliding Window
2+
===============
3+
4+
- Introduction:
5+
=============
6+
7+
The sliding window technique is a commonly used algorithmic strategy for solving problems that involve arrays or lists.
8+
This technique is particularly effective when dealing with problems related to subarrays or substrings. It involves
9+
maintaining a window that slides over the data structure to capture a subset of elements, which is then analyzed to
10+
solve the problem at hand.
11+
12+
- Here’s a brief overview of how the sliding window technique works:
13+
====================================================================
14+
15+
1. Fixed-size Window:
16+
- A window of a fixed size moves from the beginning to the end of the array.
17+
- At each step, the window captures a subset of the array's elements.
18+
- This technique is used to find the maximum/minimum sum of subarrays of a fixed size, average of subarrays, etc.
19+
20+
2. Variable-size Window:
21+
- The window size can change dynamically.
22+
- This approach is useful when the window size is determined based on a condition that changes as you iterate through the array.
23+
- It is often used in problems where you need to find the smallest or largest subarray that meets a certain condition,
24+
such as the sum being greater than a given value, or the number of distinct characters in a substring.
25+
26+
- Examples:
27+
===========
28+
29+
1. Fixed-size Window Example:
30+
31+
- Problem: Find the maximum sum of all subarrays of size `k` in an array.
32+
- Approach: To find the maximum sum of all subarrays of size `k` in an array using the sliding window technique in Java,
33+
we can follow the steps outlined below. The sliding window approach will help us achieve an optimal time complexity of O(n).
34+
35+
* Here's a Java implementation along with an explanation of the time and space complexity:
36+
37+
public class SlidingWindowMaxSum {
38+
// Method to find the maximum sum of subarrays of size k
39+
public static int maxSumSubarray(int[] arr, int k) {
40+
int n = arr.length;
41+
if (n < k) {
42+
throw new IllegalArgumentException("Array length must be greater than or equal to k");
43+
}
44+
45+
// Compute the sum of the first window of size k
46+
int maxSum = 0;
47+
for (int i = 0; i < k; i++) {
48+
maxSum += arr[i];
49+
}
50+
51+
// Initialize the current window sum to the maxSum
52+
int windowSum = maxSum;
53+
54+
// Slide the window from the start to the end of the array
55+
for (int i = k; i < n; i++) {
56+
windowSum += arr[i] - arr[i - k];
57+
maxSum = Math.max(maxSum, windowSum);
58+
}
59+
60+
return maxSum;
61+
}
62+
63+
public static void main(String[] args) {
64+
int[] arr = {1, 2, 3, 1, 4, 5, 2, 8, 1, 1};
65+
int k = 3;
66+
System.out.println("Maximum sum of subarrays of size " + k + " is " + maxSumSubarray(arr, k));
67+
}
68+
}
69+
70+
* Explanation:
71+
72+
1. Initial Sum Calculation: We first calculate the sum of the initial window of size `k`. This gives us the initial maximum sum.
73+
2. Sliding the Window: We then slide the window across the array. For each new position of the window:
74+
- Add the element that comes into the window (arr[i]).
75+
- Subtract the element that goes out of the window (arr[i - k]).
76+
- Update the maximum sum if the current window sum is greater than the previous maximum sum.
77+
78+
* Time and Space Complexity:
79+
80+
- Time Complexity:
81+
- Initial Sum Calculation: Calculating the sum of the first window takes O(k) time.
82+
- Sliding the Window: Sliding the window across the rest of the array takes O(n - k) time.
83+
- Overall, the time complexity is O(n), where (n) is the number of elements in the array.
84+
85+
- Space Complexity:
86+
- The algorithm uses a constant amount of extra space for variables (`maxSum`, `windowSum`, etc.), leading to a space
87+
complexity of O(1).
88+
89+
This implementation efficiently finds the maximum sum of all subarrays of size `k` using the sliding window technique with optimal
90+
time and space complexity.
91+
92+
93+
2. Variable-size Window Example:
94+
95+
- Problem: Find the smallest subarray with a sum greater than or equal to `S`.
96+
- Approach: To find the smallest subarray with a sum greater than or equal to `S` in an array using the sliding window technique
97+
in Java, we can follow a variable-size sliding window approach. This technique ensures that we only traverse the array once,
98+
achieving an optimal time complexity of O(n).
99+
100+
* Java Implementation:
101+
102+
public class SmallestSubarraySum {
103+
// Method to find the length of the smallest subarray with sum >= S
104+
public static int smallestSubarrayWithSum(int[] arr, int S) {
105+
int n = arr.length;
106+
int minLength = Integer.MAX_VALUE;
107+
int currentSum = 0;
108+
int start = 0;
109+
110+
for (int end = 0; end < n; end++) {
111+
currentSum += arr[end];
112+
113+
// Shrink the window as small as possible while the window's sum is larger than or equal to S
114+
while (currentSum >= S) {
115+
minLength = Math.min(minLength, end - start + 1);
116+
currentSum -= arr[start];
117+
start++;
118+
}
119+
}
120+
121+
// Return 0 if no subarray with sum >= S exists
122+
return minLength == Integer.MAX_VALUE ? 0 : minLength;
123+
}
124+
125+
public static void main(String[] args) {
126+
int[] arr = {2, 1, 5, 2, 3, 2};
127+
int S = 7;
128+
int result = smallestSubarrayWithSum(arr, S);
129+
System.out.println("The length of the smallest subarray with sum >= " + S + " is " + result);
130+
}
131+
}
132+
133+
134+
* Explanation:
135+
136+
1. Initialization: We initialize `minLength` to `Integer.MAX_VALUE` to keep track of the minimum length of the
137+
subarray found. `currentSum` is initialized to 0 to store the sum of the current window, and `start` is initialized
138+
to 0 to denote the start of the window.
139+
140+
2. Expanding the Window: We iterate over the array with the `end` pointer, adding the current element to `currentSum`.
141+
142+
3. Shrinking the Window: While the `currentSum` is greater than or equal to `S`, we try to shrink the window from the
143+
left by moving the `start` pointer to the right, updating the `minLength` with the current window size if it's smaller
144+
than the previously recorded minimum length. We subtract the element at the `start` pointer from `currentSum` before moving
145+
the `start` pointer to the right.
146+
147+
4. Check and Return: After the loop, if `minLength` is still `Integer.MAX_VALUE`, it means no valid subarray was found,
148+
and we return 0. Otherwise, we return `minLength`.
149+
150+
* Time and Space Complexity
151+
152+
- Time Complexity:
153+
- The time complexity is \(O(n)\) because each element is processed at most twice, once when expanding the window and
154+
once when shrinking it.
155+
156+
- Space Complexity:
157+
- The algorithm uses a constant amount of extra space for variables (`minLength`, `currentSum`, `start`, etc.), leading
158+
to a space complexity of \(O(1)\).
159+
160+
This implementation efficiently finds the length of the smallest subarray with a sum greater than or equal to `S` using the
161+
sliding window technique with optimal time and space complexity.
162+
163+
* Key Points:
164+
165+
- Efficiency: The sliding window technique often reduces the time complexity of problems that would otherwise require nested loops,
166+
making it O(n) instead of O(n^2).
167+
- Applications: It is widely used in string problems, subarray problems, and other scenarios where a contiguous subset of elements
168+
needs to be considered.
169+
- Adjustability: The window can be adjusted dynamically, which is useful for problems where the size of the subset isn't fixed.
170+
171+
By understanding and implementing the sliding window technique, you can solve a wide range of problems more efficiently and effectively.
172+
173+
- Sliding Window Example LeetCode Question: 632. Smallest Range Covering Elements from K Lists
174+
===============================================================================================
175+
176+
To solve the problem of finding the smallest range that includes at least one number from each of `k` sorted lists, you can use
177+
a min-heap (priority queue) combined with a sliding window approach. Here’s a step-by-step explanation and Java implementation of
178+
the algorithm (ChatGPT coded the solution 🤖).
179+
180+
* Algorithm Explanation:
181+
182+
1. Initialization:
183+
- Use a min-heap (priority queue) to keep track of the smallest element among the current elements of each list.
184+
- Track the maximum element among the current elements of each list.
185+
- Keep pointers to the current index of each list.
186+
187+
2. Heap Operations:
188+
- Insert the first element of each list into the min-heap along with its list index.
189+
- Maintain a variable to track the maximum element in the current window.
190+
191+
3. Sliding Window:
192+
- Extract the minimum element from the heap (which is the smallest element in the current window).
193+
- Calculate the current range as the difference between the maximum element and the minimum element.
194+
- Update the smallest range if the current range is smaller.
195+
- Move the pointer of the list from which the minimum element was extracted and add the next element from that list to the heap.
196+
- Continue this process until one of the lists is exhausted.
197+
198+
4. Termination:
199+
- The process terminates when one of the lists is exhausted because you can no longer form a range that includes at
200+
least one number from each list.
201+
202+
* Time and Space Complexity:
203+
204+
- Time Complexity:
205+
- Inserting and extracting from the heap takes O(log k) time, and since we perform these operations for each element, the overall
206+
complexity is O(n log k), where `n` is the total number of elements across all lists, and `k` is the number of lists.
207+
208+
- Space Complexity:
209+
- The space complexity is O(k) due to the heap which stores one element from each of the `k` lists.
210+
211+
*J ava Implementation:
212+
213+
Here’s the Java code implementing the above approach:
214+
215+
import java.util.*;
216+
217+
public class SmallestRangeFinder {
218+
219+
static class Node {
220+
int value;
221+
int listIndex;
222+
int elementIndex;
223+
224+
Node(int value, int listIndex, int elementIndex) {
225+
this.value = value;
226+
this.listIndex = listIndex;
227+
this.elementIndex = elementIndex;
228+
}
229+
}
230+
231+
public static int[] findSmallestRange(List<List<Integer>> lists) {
232+
PriorityQueue<Node> minHeap = new PriorityQueue<>(
233+
Comparator.comparingInt(n -> n.value)
234+
);
235+
236+
int max = Integer.MIN_VALUE;
237+
int rangeStart = 0, rangeEnd = Integer.MAX_VALUE;
238+
239+
// Initialize the heap with the first element from each list
240+
for (int i = 0; i < lists.size(); i++) {
241+
int value = lists.get(i).get(0);
242+
minHeap.offer(new Node(value, i, 0));
243+
max = Math.max(max, value);
244+
}
245+
246+
while (true) {
247+
// Get the minimum element from the heap
248+
Node minNode = minHeap.poll();
249+
int min = minNode.value;
250+
int listIndex = minNode.listIndex;
251+
int elementIndex = minNode.elementIndex;
252+
253+
// Update the range if the current range is smaller
254+
if (max - min < rangeEnd - rangeStart) {
255+
rangeStart = min;
256+
rangeEnd = max;
257+
}
258+
259+
// If we have reached the end of one of the lists, we can't continue
260+
if (elementIndex + 1 >= lists.get(listIndex).size()) {
261+
break;
262+
}
263+
264+
// Move to the next element in the list
265+
int nextValue = lists.get(listIndex).get(elementIndex + 1);
266+
minHeap.offer(new Node(nextValue, listIndex, elementIndex + 1));
267+
max = Math.max(max, nextValue);
268+
}
269+
270+
return new int[] {rangeStart, rangeEnd};
271+
}
272+
273+
public static void main(String[] args) {
274+
List<List<Integer>> lists = Arrays.asList(
275+
Arrays.asList(4, 10, 15, 24, 26),
276+
Arrays.asList(0, 9, 12, 20),
277+
Arrays.asList(5, 18, 22, 30)
278+
);
279+
280+
int[] result = findSmallestRange(lists);
281+
System.out.println("Smallest range is [" + result[0] + ", " + result[1] + "]");
282+
}
283+
}
284+
285+
* Explanation of the Code
286+
287+
- Node Class: This helps in storing the value of the element, its list index, and its position within the list.
288+
- Heap Initialization: The heap is initialized with the first element from each list.
289+
- Heap Operations: We extract the minimum element, update the range if necessary, and add the next element
290+
from the same list to the heap.
291+
- Termination: The loop continues until we exhaust one of the lists, ensuring the smallest range is found.
292+
293+
This approach efficiently finds the smallest range that includes at least one number from each of the `k` sorted lists.

src/Sliding_Window/Slidings_Window_Technique_Tutorial.txt

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)