Set 1: Sliding Window Maximum (Maximum of all subarrays of size k).
Given an array arr of size N and an integer K, the task is to find the maximum for each and every contiguous subarray of size K.
Examples:
Input: arr[] = {1, 2, 3, 1, 4, 5, 2, 3, 6}, K = 3
Output: 3 3 4 5 5 5 6
All contiguous subarrays of size k are
{1, 2, 3} => 3
{2, 3, 1} => 3
{3, 1, 4} => 4
{1, 4, 5} => 5
{4, 5, 2} => 5
{5, 2, 3} => 5
{2, 3, 6} => 6
Input: arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, K = 4
Output: 10 10 10 15 15 90 90
Approach: To solve this in lesser space complexity we can use two pointer technique.
- The first variable pointer iterates through the subarray and finds the maximum element of a given size K
- The second variable pointer marks the ending index of the first variable pointer i.e., (i + K – 1)th index.
- When the first variable pointer reaches the index of the second variable pointer, the maximum of that subarray has been computed and will be printed.
- The process is repeated until the second variable pointer reaches the last array index (i.e array_size – 1).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void printKMax( int a[], int n, int k)
{
if (k == 1) {
for ( int i = 0; i < n; i += 1)
cout << a[i] << " " ;
return ;
}
int p = 0,
q = k - 1,
t = p,
max = a[k - 1];
while (q <= n - 1) {
if (a[p] > max)
max = a[p];
p += 1;
if (q == p && p != n) {
cout << max << " " ;
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
int main()
{
int a[] = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = sizeof (a) / sizeof (a[0]);
int K = 3;
printKMax(a, n, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void printKMax( int a[], int n, int k)
{
if (k == 1 ) {
for ( int i = 0 ; i < n; i += 1 )
System.out.print(a[i]+ " " );
return ;
}
int p = 0 ,
q = k - 1 ,
t = p,
max = a[k - 1 ];
while (q <= n - 1 ) {
if (a[p] > max)
max = a[p];
p += 1 ;
if (q == p && p != n) {
System.out.print(max+ " " );
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
public static void main(String[] args)
{
int a[] = { 1 , 2 , 3 , 4 , 5 ,
6 , 7 , 8 , 9 , 10 };
int n = a.length;
int K = 3 ;
printKMax(a, n, K);
}
}
|
Python3
def printKMax(a, n, k):
if (k = = 1 ):
for i in range (n):
print (a[i], end = " " );
return ;
p = 0 ;
q = k - 1 ;
t = p;
max = a[k - 1 ];
while (q < = n - 1 ):
if (a[p] > max ):
max = a[p];
p + = 1 ;
if (q = = p and p ! = n):
print ( max , end = " " );
q + = 1 ;
p = t + 1 ;
t = p;
if (q < n):
max = a[q];
if __name__ = = '__main__' :
a = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
n = len (a);
K = 3 ;
printKMax(a, n, K);
|
C#
using System;
class GFG{
static void printKMax( int []a, int n, int k)
{
if (k == 1) {
for ( int i = 0; i < n; i += 1)
Console.Write(a[i]+ " " );
return ;
}
int p = 0,
q = k - 1,
t = p,
max = a[k - 1];
while (q <= n - 1) {
if (a[p] > max)
max = a[p];
p += 1;
if (q == p && p != n) {
Console.Write(max+ " " );
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
public static void Main(String[] args)
{
int []a = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = a.Length;
int K = 3;
printKMax(a, n, K);
}
}
|
Javascript
<script>
function printKMax(a, n, k)
{
if (k == 1) {
for (let i = 0; i < n; i += 1)
document.write(a[i] + " " );
return ;
}
let p = 0, q = k - 1, t = p, max = a[k - 1];
while (q <= n - 1) {
if (a[p] > max)
max = a[p];
p += 1;
if (q == p && p != n) {
document.write(max + " " );
q++;
p = ++t;
if (q < n)
max = a[q];
}
}
}
let a = [ 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 ];
let n = a.length
let K = 3;
printKMax(a, n, K);
</script>
|
Time Complexity: O(N*k)
Auxiliary Space Complexity: O(1)
Approach 2: Using Dynamic Programming:
- Firstly, divide the entire array into blocks of k elements such that each block contains k elements of the array(not always for the last block).
- Maintain two dp arrays namely, left and right.
- left[i] is the maximum of all elements that are to the left of current element(including current element) in the current block(block in which current element is present).
- Similarly, right[i] is the maximum of all elements that are to the right of current element(including current element) in the current block(block in which current element is present).
- Finally, when calculating the maximum element in any subarray of length k, we calculate the maximum of right[l] and left[r]
where l = starting index of current sub array, r = ending index of current sub array
Below is the implementation of above approach,
C++
#include <bits/stdc++.h>
using namespace std;
void printKMax( int a[], int n, int k)
{
if (k == 1) {
for ( int i = 0; i < n; i += 1)
cout << a[i] << " " ;
return ;
}
int left[n],right[n];
for ( int i=0;i<n;i++){
if (i%k == 0) left[i] = a[i];
else left[i] = max(left[i-1],a[i]);
if ((n-i)%k == 0 || i==0) right[n-1-i] = a[n-1-i];
else right[n-1-i] = max(right[n-i],a[n-1-i]);
}
for ( int i=0,j=k-1; j<n; i++,j++)
cout << max(left[j],right[i]) << ' ' ;
}
int main()
{
int a[] = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
int n = sizeof (a) / sizeof (a[0]);
int K = 3;
printKMax(a, n, K);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void printKMax( int a[], int n, int k)
{
if (k == 1 ) {
for ( int i = 0 ; i < n; i += 1 )
System.out.print(a[i] + " " );
return ;
}
int left[] = new int [n];
int right[] = new int [n];
for ( int i = 0 ; i < n; i++)
{
if (i % k == 0 )
left[i] = a[i];
else
left[i] = Math.max(left[i - 1 ], a[i]);
if ((n - i) % k == 0 || i == 0 )
right[n - 1 - i] = a[n - 1 - i];
else
right[n - 1 - i] = Math.max(right[n - i], a[n - 1 - i]);
}
for ( int i = 0 , j = k - 1 ; j < n; i++, j++)
System.out.print(Math.max(left[j], right[i]) + " " );
}
public static void main(String[] args)
{
int a[] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
int n = a.length;
int K = 3 ;
printKMax(a, n, K);
}
}
|
Python3
def printKMax(a, n, k):
if (k = = 1 ):
for i in range (n):
print (a[i],end = " " )
return
left = [ 0 for i in range (n)]
right = [ 0 for i in range (n)]
for i in range (n):
if (i % k = = 0 ):
left[i] = a[i]
else :
left[i] = max (left[i - 1 ], a[i])
if ((n - i) % k = = 0 or i = = 0 ):
right[n - 1 - i] = a[n - 1 - i]
else :
right[n - 1 - i] = max (right[n - i], a[n - 1 - i])
i = 0
j = k - 1
while j < n:
print ( max (left[j], right[i]),end = " " )
i + = 1
j + = 1
a = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
n = len (a)
K = 3
printKMax(a, n, K)
|
C#
using System;
class GFG
{
static void printKMax( int []a, int n, int k)
{
if (k == 1) {
for ( int i = 0; i < n; i += 1)
Console.Write(a[i] + " " );
return ;
}
int []left = new int [n];
int []right = new int [n];
for ( int i = 0; i < n; i++)
{
if (i % k == 0)
left[i] = a[i];
else
left[i] = Math.Max(left[i - 1], a[i]);
if ((n - i) % k == 0 || i == 0)
right[n - 1 - i] = a[n - 1 - i];
else
right[n - 1 - i] = Math.Max(right[n - i], a[n - 1 - i]);
}
for ( int i = 0, j = k - 1; j < n; i++, j++)
Console.Write(Math.Max(left[j], right[i]) + " " );
}
public static void Main(String[] args)
{
int []a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int n = a.Length;
int K = 3;
printKMax(a, n, K);
}
}
|
Javascript
<script>
function printKMax(a, n, k)
{
if (k == 1) {
for ( var i = 0; i < n; i += 1)
document.write(a[i] + " " );
return ;
}
var left = [n];
var right = [n];
for ( var i = 0; i < n; i++)
{
if (i % k == 0)
left[i] = a[i];
else
left[i] = Math.max(left[i - 1], a[i]);
if ((n - i) % k == 0 || i == 0)
right[n - 1 - i] = a[n - 1 - i];
else
right[n - 1 - i] = Math.max(right[n - i], a[n - 1 - i]);
}
for ( var i = 0, j = k - 1; j < n; i++, j++)
document.write(Math.max(left[j], right[i]) + " " );
}
var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var n = a.length;
var K = 3;
printKMax(a, n, K);
</script>
|
Time Complexity : O(n)
Auxiliary Space : O(n)