Bird
Raised Fist0
DSA Typescriptprogramming

Sliding Window Maximum Using Deque in DSA Typescript

Choose your learning style10 modes available
Mental Model
We keep track of the biggest numbers in the current window using a special list that quickly removes smaller numbers.
Analogy: Imagine a line of people waiting to enter a room. Only the tallest people stay in line because shorter ones behind them can't be the tallest in the room. When someone leaves the room, we check if they were the tallest and update the line accordingly.
Array: [2, 1, 3, 4, 6, 3, 8, 9, 10, 12, 56]
Window size k=4
Deque stores indexes of elements in decreasing order of their values
Initial:
Deque: []
Window: []
Dry Run Walkthrough
Input: array: [2, 1, 3, 4, 6, 3, 8, 9, 10, 12, 56], window size k=4
Goal: Find the maximum number in every window of size 4 as it slides from left to right
Step 1: Add index 0 (value 2) to deque
Deque: [0] (values: [2])
Why: Start with first element, deque holds indexes of potential max values
Step 2: Add index 1 (value 1) to deque after checking and keeping decreasing order
Deque: [0, 1] (values: [2, 1])
Why: 1 is smaller than 2, so it stays behind 2
Step 3: Add index 2 (value 3), remove smaller values from back (1)
Deque: [0, 2] (values: [2, 3])
Why: 3 is bigger than 1, so smaller values behind it are removed
Step 4: Add index 3 (value 4), remove smaller values from back (2)
Deque: [3] (values: [4])
Why: 4 is bigger, so remove smaller values behind it
Step 5: Window reached size 4, record max value at front index 3 (value 4)
Max so far: [4]
Why: Front of deque always holds max for current window
Step 6: Slide window: remove index 0 if out of window, add index 4 (value 6), remove smaller values (4)
Deque: [4] (values: [6])
Max so far: [4, 6]
Why: Remove old indexes outside window, keep deque decreasing
Step 7: Add index 5 (value 3), smaller than 6, so just add
Deque: [4, 5] (values: [6, 3])
Max so far: [4, 6]
Why: 3 is smaller, stays behind 6
Step 8: Add index 6 (value 8), remove smaller values (3, 6)
Deque: [6] (values: [8])
Max so far: [4, 6]
Why: 8 is bigger, remove smaller values behind it
Step 9: Slide window, remove index 1 if out, add index 7 (value 9), remove smaller values (8)
Deque: [7] (values: [9])
Max so far: [4, 6, 8]
Why: Keep deque decreasing and remove old indexes
Step 10: Add index 8 (value 10), remove smaller values (9)
Deque: [8] (values: [10])
Max so far: [4, 6, 8, 9]
Why: 10 is bigger, remove smaller values behind it
Step 11: Add index 9 (value 12), remove smaller values (10)
Deque: [9] (values: [12])
Max so far: [4, 6, 8, 9, 10]
Why: 12 is bigger, remove smaller values behind it
Step 12: Add index 10 (value 56), remove smaller values (12)
Deque: [10] (values: [56])
Max so far: [4, 6, 8, 9, 10, 12]
Why: 56 is biggest, remove smaller values behind it
Step 13: Record max for last window at index 10 (value 56)
Max so far: [4, 6, 8, 9, 10, 12, 56]
Why: Front of deque is max for current window
Result:
Max values for each window: 4 -> 6 -> 8 -> 9 -> 10 -> 12 -> 56
Annotated Code
DSA Typescript
class Deque {
  items: number[] = [];

  pushBack(value: number) {
    this.items.push(value);
  }

  popBack() {
    return this.items.pop();
  }

  popFront() {
    return this.items.shift();
  }

  front() {
    return this.items[0];
  }

  back() {
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }
}

function slidingWindowMaximum(nums: number[], k: number): number[] {
  const deque = new Deque();
  const result: number[] = [];

  for (let i = 0; i < nums.length; i++) {
    // Remove indexes out of current window
    while (!deque.isEmpty() && deque.front()! <= i - k) {
      deque.popFront(); // remove old index
    }

    // Remove smaller values from back
    while (!deque.isEmpty() && nums[deque.back()!] < nums[i]) {
      deque.popBack(); // remove smaller values
    }

    deque.pushBack(i); // add current index

    // Start adding max to result when first window is complete
    if (i >= k - 1) {
      result.push(nums[deque.front()!]); // front is max
    }
  }

  return result;
}

// Driver code
const arr = [2, 1, 3, 4, 6, 3, 8, 9, 10, 12, 56];
const k = 4;
const maxValues = slidingWindowMaximum(arr, k);
console.log(maxValues.join(' -> '));
while (!deque.isEmpty() && deque.front()! <= i - k) { deque.popFront(); }
Remove indexes that are out of the current window
while (!deque.isEmpty() && nums[deque.back()!] < nums[i]) { deque.popBack(); }
Remove smaller values from the back to keep deque decreasing
deque.pushBack(i);
Add current index to deque
if (i >= k - 1) { result.push(nums[deque.front()!]); }
Add max value for current window to result
OutputSuccess
4 -> 6 -> 8 -> 9 -> 10 -> 12 -> 56
Complexity Analysis
Time: O(n) because each element is added and removed from the deque at most once
Space: O(k) because the deque stores indexes only for the current window size
vs Alternative: Naive approach checks all k elements for each window, O(n*k), which is slower than this O(n) method
Edge Cases
Empty array
Returns empty result array without error
DSA Typescript
for (let i = 0; i < nums.length; i++) { ... }
Window size k equals 1
Each element is max of its own window, returns original array
DSA Typescript
if (i >= k - 1) { result.push(nums[deque.front()!]); }
Window size k equals array length
Returns single max value of entire array
DSA Typescript
while (!deque.isEmpty() && deque.front()! <= i - k) { deque.popFront(); }
When to Use This Pattern
When asked to find max or min in every sliding window efficiently, use a deque to keep track of candidates in decreasing order to achieve O(n) time.
Common Mistakes
Mistake: Not removing indexes that are out of the current window from the front of the deque
Fix: Add a check to pop from front when deque.front() <= i - k
Mistake: Not removing smaller values from the back before adding new index, causing incorrect max
Fix: Pop from back while nums[deque.back()] < nums[i] before pushing new index
Summary
Finds the maximum value in every sliding window of size k using a deque for efficient tracking.
Use when you need fast max queries over moving windows in an array.
Keep the deque storing indexes of elements in decreasing order and remove outdated or smaller elements as the window slides.

Practice

(1/5)
1. What is the main purpose of using a deque in the Sliding Window Maximum algorithm?
easy
A. To reverse the array elements
B. To store all elements of the array for quick access
C. To sort the entire array before processing
D. To keep track of indices of elements in the current window in decreasing order of their values

Solution

  1. Step 1: Understand the role of deque in the algorithm

    The deque stores indices of elements in the current window, maintaining them in decreasing order of their values to quickly find the maximum.
  2. Step 2: Eliminate incorrect options

    Options A, B, and C do not describe the deque's role in maintaining order or tracking maximums.
  3. Final Answer:

    To keep track of indices of elements in the current window in decreasing order of their values -> Option D
  4. Quick Check:

    Deque stores indices in decreasing order = D [OK]
Hint: Deque keeps max candidates in order for O(1) max retrieval [OK]
Common Mistakes:
  • Thinking deque stores actual values instead of indices
  • Assuming deque sorts the entire array
  • Confusing deque with a stack or queue only
2. Which of the following TypeScript code snippets correctly initializes an empty deque using an array for the Sliding Window Maximum algorithm?
easy
A. const deque: number[] = [];
B. const deque = new Deque();
C. const deque = []; deque.push(null);
D. const deque: string[] = [];

Solution

  1. Step 1: Identify correct deque initialization in TypeScript

    Using an array of numbers is the common way to simulate a deque for indices, so const deque: number[] = []; is correct.
  2. Step 2: Check other options for errors

    A pushes null which is incorrect, B uses a non-existent Deque class by default, and D uses string array which is wrong for indices.
  3. Final Answer:

    const deque: number[] = []; -> Option A
  4. Quick Check:

    Array of numbers for deque = C [OK]
Hint: Use number array for indices, no built-in Deque in TypeScript [OK]
Common Mistakes:
  • Using string array instead of number array
  • Trying to use a Deque class without importing
  • Pushing null or undefined initially
3. What is the output of the following TypeScript code snippet for sliding window maximum with window size 3?
function maxSlidingWindow(nums: number[], k: number): number[] {
  const deque: number[] = [];
  const result: number[] = [];
  for (let i = 0; i < nums.length; i++) {
    while (deque.length && nums[deque[deque.length - 1]] <= nums[i]) {
      deque.pop();
    }
    deque.push(i);
    if (deque[0] === i - k) {
      deque.shift();
    }
    if (i >= k - 1) {
      result.push(nums[deque[0]]);
    }
  }
  return result;
}

console.log(maxSlidingWindow([1,3,-1,-3,5,3,6,7], 3));
medium
A. [1, 3, -1, -3, 5, 3]
B. [3, 3, 5, 5, 6, 7]
C. [3, -1, -3, 5, 3, 6]
D. [7, 6, 5, 3, -3, -1]

Solution

  1. Step 1: Trace the sliding window maximum for each window

    Windows and their max values: [1,3,-1] -> 3 [3,-1,-3] -> 3 [-1,-3,5] -> 5 [-3,5,3] -> 5 [5,3,6] -> 6 [3,6,7] -> 7
  2. Step 2: Confirm the output array matches these max values

    The output array is [3, 3, 5, 5, 6, 7], which matches.
  3. Final Answer:

    [3, 3, 5, 5, 6, 7] -> Option B
  4. Quick Check:

    Sliding window max = [3,3,5,5,6,7] [OK]
Hint: Check max of each window manually to verify output [OK]
Common Mistakes:
  • Not removing indices outside the window
  • Incorrectly popping from deque
  • Mixing values and indices in deque
4. Identify the bug in the following Sliding Window Maximum code snippet and select the correct fix:
function maxSlidingWindow(nums: number[], k: number): number[] {
  const deque: number[] = [];
  const result: number[] = [];
  for (let i = 0; i < nums.length; i++) {
    while (deque.length && nums[deque[deque.length - 1]] < nums[i]) {
      deque.pop();
    }
    deque.push(i);
    if (deque[0] <= i - k) {
      deque.shift();
    }
    if (i >= k - 1) {
      result.push(nums[deque[0]]);
    }
  }
  return result;
}
medium
A. Change condition to 'nums[deque[deque.length - 1]] <= nums[i]' in while loop
B. Change 'deque[0] <= i - k' to 'deque[0] < i - k' in if condition
C. Remove the if condition that shifts deque
D. Change 'deque.push(i)' to 'deque.unshift(i)'

Solution

  1. Step 1: Analyze the while loop condition

    The condition 'nums[deque[deque.length - 1]] < nums[i]' does not pop elements equal to nums[i], keeping redundant candidates. It should use '<=' for strictly decreasing order.
  2. Step 2: Check other options

    B would fail to remove exactly expired indices, C removes necessary logic, D reverses order incorrectly.
  3. Final Answer:

    Change condition to 'nums[deque[deque.length - 1]] <= nums[i]' in while loop -> Option A
  4. Quick Check:

    <= in while removes equals too [OK]
Hint: Use <= in while loop to remove equal values [OK]
Common Mistakes:
  • Using < instead of <= in while loop
  • Wrong fix changing shift condition to <
  • Using unshift instead of push
5. Given an array nums = [4, 2, 12, 3, 8, 7, 9] and window size k = 4, what is the sliding window maximum output if the algorithm is modified to return the indices of maximum elements instead of values?
medium
A. [3, 4, 5, 6]
B. [0, 2, 4, 5]
C. [2, 2, 2, 6]
D. [2, 3, 4, 6]

Solution

  1. Step 1: Find max values and their indices for each window of size 4

    Windows and max indices: [4,2,12,3] (0-3) -> 2 (12) [2,12,3,8] (1-4) -> 2 (12) [12,3,8,7] (2-5) -> 2 (12) [3,8,7,9] (3-6) -> 6 (9)
  2. Step 2: Collect indices of max elements

    The indices are [2, 2, 2, 6].
  3. Final Answer:

    [2, 2, 2, 6] -> Option C
  4. Quick Check:

    Max indices per window = [2,2,2,6] [OK]
Hint: Track max element indices per window, not just values [OK]
Common Mistakes:
  • Returning values instead of indices
  • Mixing up indices when max repeats
  • Not updating max index when window slides
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard