## Sliding Window #### 2024/12/14 --- ### What is Sliding Window * Two variable `front` and `back` form a range `[front, back]`. When `front` and `back` is moving from left to right, you can perform some calculation dynamically. * Total Time Complexity is `O(N)`. >`[front, back]` is inclusive both side. ### Main Idea 1. Moving `back++` and check if `[front, back]` satisfies your requirements. 2. If not, moving `front++` until `[front, back]` satisfies your requirements. 3. Once `[front, back]` satisfies your requirements, you can perform something to the range or something you got during sliding window. ### Code ```java= for (int front = 0, back = 0; back < n; back++) { /* Section 1 */ //------------ /* do something with respect to back * example: * list.offerLast(back); */ /* Section 2 */ //------------ while (front < back && /* some "in bound" condition*/) { /* do something with respect to front * example: * list.remove(front); */ front++; } /* Section 3 */ //------------- /* calculate the answer * example: * total += back - front + 1; */ } ``` * Each Iteration: * `back++` * Section 1: initializes or updates values related to back * we have range `[front, back]` * Section 2 ensures the range `[front, back]` satisfies conditions: * `front++` until `[front, back]` is the range you require * Section 3: performs operations on the valid range * now you have a valid range `[front, back]` ### Graph * example: count the number of subarrays of length 3 ```json array = [a, b, c, d, e, f, g, h, i, j, k] f = front b = back --------------------------------- iteration 1: f [a, b, c, d, e, f, g, h, i, j, k] b --------------------------------- iteration 2: f [a, b, c, d, e, f, g, h, i, j, k] b --------------------------------- iteration 3: f [a, b, c, d, e, f, g, h, i, j, k] b count += 1 --------------------------------- iteration 4: f [a, b, c, d, e, f, g, h, i, j, k] b count += 1 --------------------------------- iteration 5: f [a, b, c, d, e, f, g, h, i, j, k] b count += 1 --------------------------------- iteration 6: f [a, b, c, d, e, f, g, h, i, j, k] b count += 1 . . . ``` --- ## Example ### LeetCode 632. Smallest Range Covering Elements from K Lists(hard) * Flatten the `2D List`, and we will get `ArrayList<Pair> arr` * Sort the `arr` according to `val` * Use sliding window * requirement:`number of group == nums.length` * result: the `front` and `back` with minimum`arr.get(back).val - arr.get(front).val)` ```java= import java.util.HashMap; import java.util.Collections; class Solution { public int[] smallestRange(List<List<Integer>> nums) { HashMap<Integer, Integer> map = new HashMap<>(); ArrayList<Pair> arr = new ArrayList<>(); for (int i = 0; i < nums.size(); i++) { for (int val : nums.get(i)) { arr.add(new Pair(i, val)); } } Collections.sort(arr, (o1, o2) -> o1.val - o2.val); int ans = Integer.MAX_VALUE; int aF = -1, aB = -1; // Sliding Window for (int front = 0, back = 0; back < arr.size(); back++) { // Section 1 int group = arr.get(back).group; map.putIfAbsent(group, 0); map.put(group, map.get(group) + 1); // Section 2 while (map.size() == nums.size() && front < arr.size() && map.get(arr.get(front).group) > 1) { int gFront = arr.get(front).group; map.put(gFront, map.get(gFront) - 1); front++; } // Section 3 if (map.size() == nums.size()) { int temp = arr.get(back).val - arr.get(front).val; if (temp < ans) { ans = temp; aF = front; aB = back; } map.remove(arr.get(front).group); front++; } } // end of Sliding Window return new int[] { arr.get(aF).val, arr.get(aB).val }; } } class Pair { int group, val; Pair (int group, int val) { this.group = group; this.val = val; } } ```