BackhardSliding Window

Maximum Values in Subsequences Solution

Problem Statement

Given an array of integers representing a discrete signal and an integer k denoting the window size, compute the maximum value within every contiguous subarray of length k as the window slides from the start to the end of the array.

The input consists of an array nums of length n and an integer k, where 1 <= k <= n. The output should be an array of length n - k + 1, where the i-th element corresponds to the maximum value in the subarray nums[i ... i + k - 1].

For example, if nums = [1, 3, -1, -3, 5, 3, 6, 7] and k = 3, the sliding windows are [1,3,-1], [3,-1,-3], [-1,-3,5], [-3,5,3], [5,3,6], and [3,6,7]. The maximums are 3, 3, 5, 5, 6, and 7 respectively.

Example 1
Input
nums = [2, 1, 5, 7, 3, 8, 4], k = 3
Output
[5, 7, 7, 8, 8]

Explanation: Window 1: [2,1,5] -> max 5. Window 2: [1,5,7] -> max 7. Window 3: [5,7,3] -> max 7. Window 4: [7,3,8] -> max 8. Window 5: [3,8,4] -> max 8.

Example 2
Input
nums = [10, -2, 4, 0, 7, 1, 9], k = 4
Output
[10, 4, 7, 9]

Explanation: Window 1: [10,-2,4,0] -> max 10. Window 2: [-2,4,0,7] -> max 7. Window 3: [4,0,7,1] -> max 7. Window 4: [0,7,1,9] -> max 9.

Example 3
Input
nums = [5, 5, 5, 5], k = 2
Output
[5, 5, 5]

Explanation: Window 1: [5,5] -> max 5. Window 2: [5,5] -> max 5. Window 3: [5,5] -> max 5.

Example 4
Input
nums = [-3, -1, -4, -2, -5], k = 3
Output
[-1, -1, -2]

Explanation: Window 1: [-3,-1,-4] -> max -1. Window 2: [-1,-4,-2] -> max -1. Window 3: [-4,-2,-5] -> max -2.

Constraints

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9
  • 1 <= k <= nums.length
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Maximum Values in Subsequences — Problem Statement & Solution Guide

Sliding WindowHardSliding Window Maximum
TimeO(n)
|
SpaceO(k)

Problem Description

Given an array of integers representing a discrete signal and an integer k denoting the window size, compute the maximum value within every contiguous subarray of length k as the window slides from the start to the end of the array.

The input consists of an array nums of length n and an integer k, where 1 <= k <= n. The output should be an array of length n - k + 1, where the i-th element corresponds to the maximum value in the subarray nums[i ... i + k - 1].

For example, if nums = [1, 3, -1, -3, 5, 3, 6, 7] and k = 3, the sliding windows are [1,3,-1], [3,-1,-3], [-1,-3,5], [-3,5,3], [5,3,6], and [3,6,7]. The maximums are 3, 3, 5, 5, 6, and 7 respectively.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Maximum Values in Subsequences"

hard

WHY DOES IT MATTER?

Sliding‑window maximum is a canonical example of the monotonic queue pattern, which appears in real‑time analytics, stock‑price monitoring, and any scenario requiring fast, rolling aggregates. Mastering this pattern equips engineers to design low‑latency services that process streams without recomputing from scratch.

OPTIMIZATION CHALLENGE

The breakthrough is recognizing that any element smaller than a newer element can never become the maximum while the newer one remains in the window, allowing us to prune it immediately. This pruning ensures each element is processed O(1) times overall, collapsing the naïve O(n·k) bound to O(n).

REAL-WORLD CONNECTION

Think of a moving surveillance camera that continuously records the highest temperature in its field of view. Instead of re‑scanning every pixel each frame, the system keeps a list of candidate hot spots; as the view shifts, outdated spots are discarded and new hotter spots replace weaker ones, mirroring the deque’s behavior.

During an interview, implement the deque first, then add the two housekeeping steps: (1) pop indices that are out of the current window range, and (2) maintain decreasing order by popping smaller values from the back before pushing the new index.

COMPLEXITY AT A GLANCE

⏱ Time:O(n)
đź’ľ Space:O(k)

Core Theory — Why This Approach?

The sliding‑window maximum problem asks for the greatest element in every contiguous subarray of size k. A naïve solution recomputes the maximum for each window by scanning k elements, leading to O(n·k) time, which becomes prohibitive when n and k approach 10^5 or larger. The optimal solution relies on a monotonic deque (double‑ended queue) that stores indices of candidates in decreasing order of their values. As the window slides, elements that fall out of the window are removed from the front, and any new element that is smaller than the deque’s tail is discarded because it can never become a maximum while a larger element remains in the window. This invariant guarantees that the deque’s front always holds the index of the current window’s maximum.

By maintaining this structure, each array element is inserted and removed at most once, yielding linear O(n) time. The space usage is O(k) in the worst case, but often much smaller because the deque holds only a subset of indices that are potential maxima. This paradigm exemplifies the broader class of problems solvable with monotonic data structures, where ordering constraints enable amortized constant‑time updates while preserving essential information for each window.

The approach also generalizes to other sliding‑window aggregates (minimum, sum, count of distinct elements) by swapping the monotonic condition or augmenting the deque with auxiliary data. Understanding why the naïve method fails and how the monotonic deque enforces a strict ordering is key to mastering hard‑level sliding‑window challenges in interviews.

Interview Questions on This Problem

Q1How would you modify the monotonic deque solution to return the minimum of each sliding window instead of the maximum?

Use an increasing deque instead of a decreasing one: while the deque’s tail holds values greater than the incoming element, pop them. The front then always contains the index of the minimum for the current window.

Q2Can you solve the sliding‑window maximum problem in O(n log k) time without a deque? If so, describe the method.

Yes, by using a balanced binary search tree (e.g., multiset) or a max‑heap with lazy deletion. Insert each new element and remove the element that slides out; the tree/heap’s top gives the current maximum, leading to O(log k) per operation and O(n log k) total.

Q3Explain how you would handle the case where k equals 1 or n in your implementation, and why these edge cases are trivial.

When k = 1, each window contains a single element, so the output is the original array; the algorithm can return a copy directly. When k = n, there is only one window covering the whole array, so the answer is the global maximum, which can be found with a single linear scan.

Examples

Example 1

Input

nums = [2, 1, 5, 7, 3, 8, 4], k = 3

Output

[5, 7, 7, 8, 8]

Explanation: Window 1: [2,1,5] -> max 5. Window 2: [1,5,7] -> max 7. Window 3: [5,7,3] -> max 7. Window 4: [7,3,8] -> max 8. Window 5: [3,8,4] -> max 8.

Example 2

Input

nums = [10, -2, 4, 0, 7, 1, 9], k = 4

Output

[10, 4, 7, 9]

Explanation: Window 1: [10,-2,4,0] -> max 10. Window 2: [-2,4,0,7] -> max 7. Window 3: [4,0,7,1] -> max 7. Window 4: [0,7,1,9] -> max 9.

Example 3

Input

nums = [5, 5, 5, 5], k = 2

Output

[5, 5, 5]

Explanation: Window 1: [5,5] -> max 5. Window 2: [5,5] -> max 5. Window 3: [5,5] -> max 5.

Example 4

Input

nums = [-3, -1, -4, -2, -5], k = 3

Output

[-1, -1, -2]

Explanation: Window 1: [-3,-1,-4] -> max -1. Window 2: [-1,-4,-2] -> max -1. Window 3: [-4,-2,-5] -> max -2.

Constraints

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9
  • 1 <= k <= nums.length

Optimal Approach & Strategy

Maintain a decreasing deque of indices, updating it in O(1) amortized time per element so each element is processed only twice.

Brute Force Approach

For each window, scan all k elements to find the maximum, repeating this for every possible window.

Verified Code Solutions

JavaScript Solution
Time: O(n)
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    const result = [];
    const dq = []; // Stores indices
    
    for (let i = 0; i < nums.length; i++) {
        // Remove indices out of the current window
        if (dq.length > 0 && dq[0] <= i - k) {
            dq.shift();
        }
        
        // Remove indices of elements smaller than the current element
        while (dq.length > 0 && nums[dq[dq.length - 1]] <= nums[i]) {
            dq.pop();
        }
        
        dq.push(i);
        
        // The front of the deque is the index of the max element in the current window
        if (i >= k - 1) {
            result.push(nums[dq[0]]);
        }
    }
    
    return result;
};

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.