Sliding Window Maximum (Maximum of All Subarrays of Size K)

Last Updated : 24 Jul, 2026

Given an array arr[] of positive integers and an integer k. Find the maximum value for each contiguous subarray of size k.

Return an array of maximum values corresponding to each contiguous subarray.

Examples : 

Input: arr[] = [1, 2, 3, 1, 4, 5, 2, 3, 6], k = 3
Output: [3, 3, 4, 5, 5, 5, 6]
Explanation:
1st contiguous subarray = [1 2 3] max = 3
2nd contiguous subarray = [2 3 1] max = 3
3rd contiguous subarray = [3 1 4] max = 4
4th contiguous subarray = [1 4 5] max = 5
5th contiguous subarray = [4 5 2] max = 5
6th contiguous subarray = [5 2 3] max = 5
7th contiguous subarray = [2 3 6] max = 6

Input: arr[] = [5, 1, 3, 4, 2, 6], k = 1
Output: [5, 1, 3, 4, 2, 6]
Explanation: When k = 1, each element in the array is its own subarray, so the output is simply the same array.

Try It Yourself
redirect icon

[Naive Approach] - Using Nested Loops - O(n * k) Time and O(1) Space

The idea is to run the nested loops, the outer loop will mark the starting point of the subarray of length k, and the inner loop will run from the starting index to index + k, and print the maximum element among these k elements. 

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> maxOfSubarrays(vector<int>& arr, int k) {
    int n = arr.size();

    // to store the results
    vector<int> res;
  
    for (int i = 0; i <= n - k; i++) {
      
        // Find maximum of subarray beginning
        // with arr[i]
        int max = arr[i];
        for (int j = 1; j < k; j++) {
            if (arr[i + j] > max)
                max = arr[i + j];
        }
        res.push_back(max);
    }
  
    return res;
}

int main() {
    vector<int> arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
    int k = 3;
    vector<int> res = maxOfSubarrays(arr, k);
    for (int maxVal : res) {
        cout << maxVal << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;

class GFG {
    static ArrayList<Integer> maxOfSubarrays(int[] arr, int k) {
        int n = arr.length;

        // to store the results
        ArrayList<Integer> res = new ArrayList<Integer>();
      
        for (int i = 0; i <= n - k; i++) {
      
            // Find maximum of subarray beginning
            // with arr[i]
            int max = arr[i];
            for (int j = 1; j < k; j++) {
                if (arr[i + j] > max)
                    max = arr[i + j];
            }
            res.add(max);
        }
      
        return res;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
        int k = 3;
        ArrayList<Integer> res = maxOfSubarrays(arr, k);
        for (int maxVal : res) {
            System.out.print(maxVal + " ");
        }
    }
}
Python
def maxOfSubarrays(arr, k):
    n = len(arr)

    # to store the results
    res = []
  
    for i in range(0, n - k + 1):
      
        # Find maximum of subarray beginning
        # with arr[i]
        max = arr[i]
        for j in range(1, k):
            if arr[i + j] > max:
                max = arr[i + j]
        res.append(max)
  
    return res

if __name__ == "__main__":
    arr = [ 1, 2, 3, 1, 4, 5, 2, 3, 6 ]
    k = 3
    res = maxOfSubarrays(arr, k)
    for maxVal in res:
        print(maxVal, end=" ")
C#
using System;
using System.Collections.Generic;

class GFG {
    static List<int> maxOfSubarrays(int[] arr, int k) {
        int n = arr.Length;

        // to store the results
        List<int> res = new List<int>();
  
        for (int i = 0; i <= n - k; i++) {
      
            // Find maximum of subarray beginning
            // with arr[i]
            int max = arr[i];
            for (int j = 1; j < k; j++) {
                if (arr[i + j] > max)
                    max = arr[i + j];
            }
            res.Add(max);
        }
  
        return res;
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
        int k = 3;
        List<int> res = maxOfSubarrays(arr, k);
        foreach (int maxVal in res) {
            Console.Write(maxVal + " ");
        }
    }
}
Javascript
function maxOfSubarrays(arr, k) {
    let n = arr.length;

    // to store the results
    let res = [];
  
    for (let i = 0; i <= n - k; i++) {
      
        // Find maximum of subarray beginning
        // with arr[i]
        let max = arr[i];
        for (let j = 1; j < k; j++) {
            if (arr[i + j] > max)
                max = arr[i + j];
        }
        res.push(max);
    }
  
    return res;
}

// Driver Code
let arr = [ 1, 2, 3, 1, 4, 5, 2, 3, 6 ];
let k = 3;
let res = maxOfSubarrays(arr, k);
console.log(res.join(" "));

Output
3 3 4 5 5 5 6 

[Better Approach] - Using Max-Heap - (n * log n) Time and O(n) Space

The idea is to use priority queue or heap data structure to make sure that heap has largest item of the current window. Create a max heap of the first k items. Now iterate one by one. While the next item to be added is greater than the heap top, remove the top. We mainly make sure that the greater items of the previous window are not there in a heap.

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> maxOfSubarrays(const vector<int>& arr, int k) {
    int n = arr.size();

    // to store the results
    vector<int> res;

    // to store the max value
    priority_queue<pair<int, int> > heap;

    // Initialize the heap with the first k elements
    for (int i = 0; i < k; i++)
        heap.push({ arr[i], i });

    // The maximum element in the first window
    res.push_back(heap.top().first);

    // Process the remaining elements
    for (int i = k; i < arr.size(); i++) {

        // Add the current element to the heap
        heap.push({ arr[i], i });

        // Remove elements that are outside the current
        // window
        while (heap.top().second <= i - k)
            heap.pop();

        // The maximum element in the current window
        res.push_back(heap.top().first);
    }

    return res;
}

int main() {
    vector<int> arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
    int k = 3;
    vector<int> res = maxOfSubarrays(arr, k);
    for (int maxVal : res) {
        cout << maxVal << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

class GFG {

    static ArrayList<Integer> maxOfSubarrays(int[] arr, int k) {
        int n = arr.length;

        // to store the results
        ArrayList<Integer> res = new ArrayList<Integer>();

        // to store the max value
        PriorityQueue<Pair> heap = new PriorityQueue<Pair>(new Comparator<Pair>() {
            public int compare(Pair a, Pair b) {
                return b.first - a.first;
            }
        });

        // Initialize the heap with the first k elements
        for (int i = 0; i < k; i++)
            heap.add(new Pair(arr[i], i));

        // The maximum element in the first window
        res.add(heap.peek().first);

        // Process the remaining elements
        for (int i = k; i < arr.length; i++) {

            // Add the current element to the heap
            heap.add(new Pair(arr[i], i));

            // Remove elements that are outside the current
            // window
            while (heap.peek().second <= i - k)
                heap.poll();

            // The maximum element in the current window
            res.add(heap.peek().first);
        }

        return res;
    }

    static class Pair {
        int first;
        int second;
        Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
        int k = 3;
        ArrayList<Integer> res = maxOfSubarrays(arr, k);
        for (int maxVal : res) {
            System.out.print(maxVal + " ");
        }
    }
}
Python
import heapq

def maxOfSubarrays(arr, k):
    n = len(arr)

    # to store the results
    res = []

    # to store the max value
    heap = []

    # Initialize the heap with the first k elements
    for i in range(0, k):
        heapq.heappush(heap, (-arr[i], i))

    # The maximum element in the first window
    res.append(-heap[0][0])

    # Process the remaining elements
    for i in range(k, len(arr)):

        # Add the current element to the heap
        heapq.heappush(heap, (-arr[i], i))

        # Remove elements that are outside the current
        # window
        while heap[0][1] <= i - k:
            heapq.heappop(heap)

        # The maximum element in the current window
        res.append(-heap[0][0])

    return res

if __name__ == "__main__":
    arr = [ 1, 2, 3, 1, 4, 5, 2, 3, 6 ]
    k = 3
    res = maxOfSubarrays(arr, k)
    for maxVal in res:
        print(maxVal, end=" ")
C#
using System;
using System.Collections.Generic;

class GFG {

    static List<int> maxOfSubarrays(int[] arr, int k) {
        int n = arr.Length;

        // to store the results
        List<int> res = new List<int>();

        // to store the max value
        // Using SortedSet to simulate a max-heap
        SortedSet<Pair> heap = new SortedSet<Pair>(new PairComparer());

        // Initialize the heap with the first k elements
        for (int i = 0; i < k; i++)
            heap.Add(new Pair(arr[i], i));

        // The maximum element in the first window
        res.Add(heap.Min.first);

        // Process the remaining elements
        for (int i = k; i < arr.Length; i++) {

            // Add the current element to the heap
            heap.Add(new Pair(arr[i], i));

            // Remove elements that are outside the current
            // window
            while (heap.Min.second <= i - k)
                heap.Remove(heap.Min);

            // The maximum element in the current window
            res.Add(heap.Min.first);
        }

        return res;
    }

    class Pair {
        public int first;
        public int second;
        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }
    }

    class PairComparer : IComparer<Pair> {
        public int Compare(Pair a, Pair b) {
            if (a.first != b.first)
                return b.first.CompareTo(a.first);
            return a.second.CompareTo(b.second);
        }
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 1, 4, 5, 2, 3, 6 };
        int k = 3;
        List<int> res = maxOfSubarrays(arr, k);
        foreach (int maxVal in res) {
            Console.Write(maxVal + " ");
        }
    }
}
Javascript
class MaxHeap {
    constructor() {
        this.heap = [];
    }

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

    // Compare two nodes (larger value first)
    compare(a, b) {
        if (a.value !== b.value)
            return a.value > b.value;

        return a.index > b.index;
    }

    push(node) {
        this.heap.push(node);
        this.heapifyUp(this.heap.length - 1);
    }

    pop() {
        if (this.heap.length === 1)
            return this.heap.pop();

        const root = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.heapifyDown(0);

        return root;
    }

    top() {
        return this.heap[0];
    }

    heapifyUp(index) {
        while (index > 0) {
            let parent = Math.floor((index - 1) / 2);

            if (this.compare(this.heap[parent], this.heap[index]))
                break;

            [this.heap[parent], this.heap[index]] =
                [this.heap[index], this.heap[parent]];

            index = parent;
        }
    }

    heapifyDown(index) {
        let size = this.heap.length;

        while (true) {
            let largest = index;
            let left = 2 * index + 1;
            let right = 2 * index + 2;

            if (left < size &&
                this.compare(this.heap[left], this.heap[largest]))
                largest = left;

            if (right < size &&
                this.compare(this.heap[right], this.heap[largest]))
                largest = right;

            if (largest === index)
                break;

            [this.heap[index], this.heap[largest]] =
                [this.heap[largest], this.heap[index]];

            index = largest;
        }
    }
}

function maxOfSubarrays(arr, k) {
    let res = [];
    let heap = new MaxHeap();

    // Insert first k elements
    for (let i = 0; i < k; i++)
        heap.push({ value: arr[i], index: i });

    res.push(heap.top().value);

    // Process remaining elements
    for (let i = k; i < arr.length; i++) {

        heap.push({ value: arr[i], index: i });

        // Remove elements outside the current window
        while (heap.top().index <= i - k)
            heap.pop();

        res.push(heap.top().value);
    }

    return res;
}

// Driver Code
let arr = [1, 2, 3, 1, 4, 5, 2, 3, 6];
let k = 3;

console.log(maxOfSubarrays(arr, k).join(" "));

Output
3 3 4 5 5 5 6 

[Expected Approach] - Using Deque - O(n) Time and O(k) Space

Create a Deque, dq of capacity k, that stores only useful elements of current window of k elements. An element is useful if it is in current window and is greater than all other elements on right side of it in current window. Process all array elements one by one and maintain dq to contain useful elements of current window and these useful elements are maintained in sorted order. The element at front of the dq is the largest and element at rear/back of dq is the smallest of current window.

Illustration:


Step-by-Step Algorithm:

  • Create a deque to store indices of useful elements for the current window.
  • Process the first k elements of the array:
  • Remove elements from the back of the deque while they are smaller than the current element, then insert the current element’s index at the back.
  • Traverse the array from index k to the end:
  • Print the element at the front of the deque as it represents the maximum of the previous window.
  • Remove the front element of the deque if it is outside the current window.
  • For the current element, remove all elements from the back of the deque that are smaller than it, then insert its index at the back.
  • After the loop ends, print the element at the front of the deque as the maximum of the last window.
C++
#include <iostream>
#include <vector>
#include <deque>

using namespace std;

vector<int> maxOfSubarrays(vector<int>& arr, int k) {

    // to store the results
    vector<int> res;
  
    // create deque to store max values
    deque<int> dq(k);

    // Process first k (or first window) elements of array
    for (int i = 0; i < k; ++i) {
      
        // For every element, the previous smaller elements 
        // are useless so remove them from dq
        while (!dq.empty() && arr[i] >= arr[dq.back()]) {
          
            // Remove from rear
            dq.pop_back();
        }

        // Add new element at rear of queue
        dq.push_back(i);
    }

    // Process rest of the elements, i.e., from arr[k] to arr[n-1]
    for (int i = k; i < arr.size(); ++i) {
      
        // The element at the front of the queue is the largest 
        // element of previous window, so store it
        res.push_back(arr[dq.front()]);

        // Remove the elements which are out of this window
        while (!dq.empty() && dq.front() <= i - k) {
          
            // Remove from front of queue
            dq.pop_front();
        }

        // Remove all elements smaller than the currently being 
        // added element (remove useless elements)
        while (!dq.empty() && arr[i] >= arr[dq.back()]) {
            dq.pop_back();
        }

        // Add current element at the rear of dq
        dq.push_back(i);
    }

    // store the maximum element of last window
    res.push_back(arr[dq.front()]);

    return res;
}

int main() {
    vector<int> arr = {1, 2, 3, 1, 4, 5, 2, 3, 6};
    int k = 3;
    vector<int> res = maxOfSubarrays(arr, k);
    for (int maxVal : res) {
        cout << maxVal << " ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Deque;
import java.util.ArrayDeque;

class GFG {

    static ArrayList<Integer> maxOfSubarrays(int[] arr, int k) {
        int n = arr.length;

        // to store the results
        ArrayList<Integer> res = new ArrayList<Integer>();

        // create deque to store max values
        Deque<Integer> dq = new ArrayDeque<Integer>();

        // Process first k (or first window) elements of array
        for (int i = 0; i < k; ++i) {
          
            // For every element, the previous smaller elements 
            // are useless so remove them from dq
            while (!dq.isEmpty() && arr[i] >= arr[dq.peekLast()]) {
              
                // Remove from rear
                dq.pollLast();
            }

            // Add new element at rear of queue
            dq.addLast(i);
        }

        // Process rest of the elements, i.e., from arr[k] to arr[n-1]
        for (int i = k; i < arr.length; ++i) {
          
            // The element at the front of the queue is the largest 
            // element of previous window, so store it
            res.add(arr[dq.peekFirst()]);

            // Remove the elements which are out of this window
            while (!dq.isEmpty() && dq.peekFirst() <= i - k) {
              
                // Remove from front of queue
                dq.pollFirst();
            }

            // Remove all elements smaller than the currently being 
            // added element (remove useless elements)
            while (!dq.isEmpty() && arr[i] >= arr[dq.peekLast()]) {
                dq.pollLast();
            }

            // Add current element at the rear of dq
            dq.addLast(i);
        }

        // store the maximum element of last window
        res.add(arr[dq.peekFirst()]);

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 1, 4, 5, 2, 3, 6};
        int k = 3;
        ArrayList<Integer> res = maxOfSubarrays(arr, k);
        for (int maxVal : res) {
            System.out.print(maxVal + " ");
        }
    }
}
Python
from collections import deque

def maxOfSubarrays(arr, k):
    n = len(arr)

    # to store the results
    res = []
  
    # create deque to store max values
    dq = deque()

    # Process first k (or first window) elements of array
    for i in range(0, k):
      
        # For every element, the previous smaller elements 
        # are useless so remove them from dq
        while dq and arr[i] >= arr[dq[-1]]:
          
            # Remove from rear
            dq.pop()

        # Add new element at rear of queue
        dq.append(i)

    # Process rest of the elements, i.e., from arr[k] to arr[n-1]
    for i in range(k, len(arr)):
      
        # The element at the front of the queue is the largest 
        # element of previous window, so store it
        res.append(arr[dq[0]])

        # Remove the elements which are out of this window
        while dq and dq[0] <= i - k:
          
            # Remove from front of queue
            dq.popleft()

        # Remove all elements smaller than the currently being 
        # added element (remove useless elements)
        while dq and arr[i] >= arr[dq[-1]]:
            dq.pop()

        # Add current element at the rear of dq
        dq.append(i)

    # store the maximum element of last window
    res.append(arr[dq[0]])

    return res

if __name__ == "__main__":
    arr = [1, 2, 3, 1, 4, 5, 2, 3, 6]
    k = 3
    res = maxOfSubarrays(arr, k)
    for maxVal in res:
        print(maxVal, end=" ")
C#
using System;
using System.Collections.Generic;

class GFG {

    static List<int> maxOfSubarrays(int[] arr, int k) {
        int n = arr.Length;

        // to store the results
        List<int> res = new List<int>();

        // create deque to store max values
        LinkedList<int> dq = new LinkedList<int>();

        // Process first k (or first window) elements of array
        for (int i = 0; i < k; ++i) {
          
            // For every element, the previous smaller elements 
            // are useless so remove them from dq
            while (dq.Count > 0 && arr[i] >= arr[dq.Last.Value]) {
              
                // Remove from rear
                dq.RemoveLast();
            }

            // Add new element at rear of queue
            dq.AddLast(i);
        }

        // Process rest of the elements, i.e., from arr[k] to arr[n-1]
        for (int i = k; i < arr.Length; ++i) {
          
            // The element at the front of the queue is the largest 
            // element of previous window, so store it
            res.Add(arr[dq.First.Value]);

            // Remove the elements which are out of this window
            while (dq.Count > 0 && dq.First.Value <= i - k) {
              
                // Remove from front of queue
                dq.RemoveFirst();
            }

            // Remove all elements smaller than the currently being 
            // added element (remove useless elements)
            while (dq.Count > 0 && arr[i] >= arr[dq.Last.Value]) {
                dq.RemoveLast();
            }

            // Add current element at the rear of dq
            dq.AddLast(i);
        }

        // store the maximum element of last window
        res.Add(arr[dq.First.Value]);

        return res;
    }

    static void Main() {
        int[] arr = {1, 2, 3, 1, 4, 5, 2, 3, 6};
        int k = 3;
        List<int> res = maxOfSubarrays(arr, k);
        foreach (int maxVal in res) {
            Console.Write(maxVal + " ");
        }
    }
}
Javascript
function maxOfSubarrays(arr, k) {
    let n = arr.length;

    // to store the results
    let res = [];

    // create deque to store max values
    let dq = [];

    // Process first k (or first window) elements of array
    for (let i = 0; i < k; ++i) {
      
        // For every element, the previous smaller elements 
        // are useless so remove them from dq
        while (dq.length > 0 && arr[i] >= arr[dq[dq.length - 1]]) {
              
            // Remove from rear
            dq.pop();
        }

        // Add new element at rear of queue
        dq.push(i);
    }

    // Process rest of the elements, i.e., from arr[k] to arr[n-1]
    for (let i = k; i < arr.length; ++i) {
      
        // The element at the front of the queue is the largest 
        // element of previous window, so store it
        res.push(arr[dq[0]]);

        // Remove the elements which are out of this window
        while (dq.length > 0 && dq[0] <= i - k) {
              
            // Remove from front of queue
            dq.shift();
        }

        // Remove all elements smaller than the currently being 
        // added element (remove useless elements)
        while (dq.length > 0 && arr[i] >= arr[dq[dq.length - 1]]) {
            dq.pop();
        }

        // Add current element at the rear of dq
        dq.push(i);
    }

    // store the maximum element of last window
    res.push(arr[dq[0]]);

    return res;
}

// Driver Code
let arr = [1, 2, 3, 1, 4, 5, 2, 3, 6];
let k = 3;
let res = maxOfSubarrays(arr, k);
console.log(res.join(" "));

Output
3 3 4 5 5 5 6 

Below is an extension of this problem: 
Sum of minimum and maximum elements of all subarrays of size k.

Comment