Maximum of all subarrays of size k (Added a O(n) method)

Given an array and an integer k, 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

Input :
arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}
k = 4
Output :
10 10 10 15 15 90 90

We strongly recommend that you click here and practice it, before moving on to the solution.


Method 1 (Simple)
Run two loops. In the outer loop, take all subarrays of size k. In the inner loop, get the maximum of the current subarray.

#include<stdio.h>

void printKMax(int arr[], int n, int k)
{
    int j, max;

    for (int i = 0; i <= n-k; i++)
    {
        max = arr[i];

        for (j = 1; j < k; j++)
        {
            if (arr[i+j] > max)
               max = arr[i+j];
        }
        printf("%d ", max);
    }
}


int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 3;
    printKMax(arr, n, k);
    return 0;
}

Time Complexity: The outer loop runs n-k+1 times and the inner loop runs k times for every iteration of outer loop. So time complexity is O((n-k+1)*k) which can also be written as O(nk).



Method 2 (Use Self-Balancing BST)
1) Pick first k elements and create a Self-Balancing Binary Search Tree (BST) of size k.
2) Run a loop for i = 0 to n – k
…..a) Get the maximum element from the BST, and print it.
…..b) Search for arr[i] in the BST and delete it from the BST.
…..c) Insert arr[i+k] into the BST.

Time Complexity: Time Complexity of step 1 is O(kLogk). Time Complexity of steps 2(a), 2(b) and 2(c) is O(Logk). Since steps 2(a), 2(b) and 2(c) are in a loop that runs n-k+1 times, time complexity of the complete algorithm is O(kLogk + (n-k+1)*Logk) which can also be written as O(nLogk).



Method 3 (A O(n) method: use Dequeue)
We create a Dequeue, Qi 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 left side of it in current window. We process all array elements one by one and maintain Qi to contain useful elements of current window and these useful elements are maintained in sorted order. The element at front of the Qi is the largest and element at rear of Qi is the smallest of current window. Thanks to Aashish for suggesting this method.

Following is C++ implementation of this method.

#include <iostream>
#include <deque>

using namespace std;

// A Dequeue (Double ended queue) based method for printing maixmum element of
// all subarrays of size k
void printKMax(int arr[], int n, int k)
{
    // Create a Double Ended Queue, Qi that will store indexes of array elements
    // The queue will store indexes of useful elements in every window and it will
    // maintain decreasing order of values from front to rear in Qi, i.e., 
    // arr[Qi.front[]] to arr[Qi.rear()] are sorted in decreasing order
    std::deque<int>  Qi(k);

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

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

    // Process rest of the elements, i.e., from arr[k] to arr[n-1]
    for ( ; i < n; ++i)
    {
        // The element at the front of the queue is the largest element of
        // previous window, so print it
        cout << arr[Qi.front()] << " ";

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

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

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

    // Print the maximum element of last window
    cout << arr[Qi.front()];
}

// Driver program to test above functions
int main()
{
    int arr[] = {12, 1, 78, 90, 57, 89, 56};
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 3;
    printKMax(arr, n, k);
    return 0;
}

Output:

78 90 90 90 89

Time Complexity: O(n). It seems more than O(n) at first look. If we take a closer look, we can observe that every element of array is added and removed at most once. So there are total 2n operations.
Auxiliary Space: O(k)

Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem.



Company Wise Coding Practice    Topic Wise Coding Practice





Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the link here.

  • typing..

    I have an algo, which works on O(n), and uses Q, without sorting..

    maintain a queue Q[k]

    1. start from arr[0], push Ist element in Q., set temporary variable t=k

    2. do for all next elements

    i. if arr[i]>arr[i-1], push in Q, t–,

    ii. if t==1, then,
    { if( Q==empty),
    print arr[i-k+1];
    else
    pop from Q until (Q->next > Q->current)
    print Q->current and pop Q->current
    set t=k;
    }

    plz, correct me if it is wrong….

  • Manisha Chopra

    We can do this in O(n) without using any auxiliary space. Java implementation of the method is as follows :

    public void printMax(int[] arr){
    int max = -1;
    for(int i=0;i max ? arr[i] : max;
    if(i >= k-1){
    System.out.print(max+” “);
    }
    }
    }

    Let me know if there is an issue

  • Rohit Sharma

    //here is simple program with time complexity-0(n)

    #include

    void print_k_max(int [],int,int);

    int maximum(int,int);

    int main()

    {

    int a[100],n,k;

    printf(“nEnter the value of n :”);

    scanf(“%d”,&n);

    printf(“nEnter the elements :n”);

    for(int i=0;i<n;i++)

    scanf("%d",&a[i]);

    printf("nEnter the value of k :");

    scanf("%d",&k);

    print_k_max(a,n,k);

    printf("nThe maximum of all subarray of k :n");

    for(int i=0;i<n-k+1;i++)

    printf("%d ",a[i]);

    return 0;

    }

    void print_k_max(int a[],int n,int k)

    {

    int max=a[0],l=0;

    for(int i=0;i max)

    max=a[i];

    }

    a[l++]=max;

    for(int i=k;i y)

    return x;

    else

    return y;

    }

  • I think we can do this with HEAP too, Self-balancing tree have extra burden, where HEAP don’t what you suggest?

  • Vikrant

    java implementation

    http://ideone.com/83yTvU

  • // Question:-Find maximum for every window of size k in an array.

    /*ALGORITHM

    Assumptions SIZE OF ARRAY=n , SUBARRAY SIZE=k , OUTPUT NUMBERS=(n-w+1)

    1)Traverse from LEFT TO RIGHT after every k’th element (k%3==0) do max=0 and save max element in LEFT_TO_RIGHT[] array in each iteration.

    2)Do the same in RIGHT TO LEFT Traversal and fill RIGHT_TO_LEFT[] array with max elements.

    3)Start a for loop to print output start=0 end=n-k(i. e. the number of outputs to be printed). In this for loop compare as following

    if max_val[] is the array to be printed in the for loop compare as following

    max_val[index] = max(RL[index], LR[index+k-1]); */

    // This algorithm works with any type of array such as ascending,descending or random.

    //Time complexity of this algorithm is O(n)

    //Extra space used is 2 array used lr[n] and rl[n]

    #include

    #include

    int main()

    {

    int arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

    int n = sizeof(arr)/sizeof(arr[0]);

    int k = 3;

    printKMax(arr, n, k);

    return 0;

    }

    void printKMax(int arr[], int n, int k)

    {

    int i,max,count,lr[n],rl[n];

    //int max1[n-k+1];

    max=0;

    count=0;

    //Traverse from left to right

    for(i=0;imax)

    {

    max=arr[i];

    lr[i]=max;

    }

    else

    {

    lr[i]=max;

    }

    }

    //Traverse from right to left

    for(i=(n-1);i>=0;i–)

    {

    count++;

    if(count%3==0)

    max=0; // making max=0 after each k size subarray

    if(arr[i]>max)

    {

    max=arr[i];

    rl[i]=max;

    }

    else

    {

    rl[i]=max;

    }

    }

    for(i=0;ilr[i+k-1]) // comparison made easy

    {

    //max1[i]=rl[i];

    printf(“%d”,rl[i]);

    }

    else

    {

    //max1[i]=lr[i+k-1];

    printf(“%d”,lr[i+k-1]);

    }

    }

    }

  • wgpshashank

    I believe 2nd method wont work as described but we can modify that as written below

    Create a AVL/RB Tree of size k . it will take O(klogk) in this every node will have counter associated with it on the basis of which we will decided which element to remove from tree , here we need to decide on the basis of two things ?
    for i=1 to n elements
    1. we will always remove the element whose counter value becomes equal to k , it wont make any sense to keep it for remaining window of size k .
    2. else if counter of all elements are equals we will always discard the minimum from tree of window.
    and finally insert the new element from array e.g i+kth-1 element in tree
    So here we doing two operation deletion and insertion , both takes O(logn) time in balanced binary search tree like RB or AVL Tree.

    so complexity will be O(nlogk) which is better then O(nk) . Obliviously some optimization can be done here . let me know if it fail for any case .

  • Shashank

    Third method is O(n*k) for worst-case time complexity, not O(n). And you don’t need a queue to do method 3. Using a queue is just wasting space. This site has some false answers so be careful!

  • Ajay

    #include

    #include

    void printkMax(int arr[],int n, int k)
    {
    int max,i;
    for(i=0;i<k;i++)
    {
    max = arr[i];
    if(max<arr[i])
    max = arr[i];
    }
    printf("%dt",max);
    for(int j = k;j<n;j++)
    {
    if(max<arr[j])
    {
    max=arr[j];
    printf("%dt",max);
    }
    else
    printf("%dt",max);
    }
    }
    int main()
    {
    int arr[] = {12,1,78,90,57,89,56};
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 3;
    printkMax(arr,n,k);
    getchar();
    return 0;
    }

  • asunel

    It can done in O(n) time and without extra space !!

    See http://ajscodeblog.blogspot.in/2013/10/maximum-of-all-subarrays-of-size-k-in.html

  • vanathi

    private void maxSubArray(int[] ar,int k){
    int max = ar[0];
    for(int i=1;i<k;i++)
    if(max < ar[i])
    max = ar[i];
    System.out.println(max);
    for(int i= k;i<ar.length;i++){
    if(max < ar[i])
    max = ar[i];
    System.out.println(max);
    }
    }

  • Apurvkagrawal

    For method 3 : can you tell me how is it O(n) for an sorted array in decreasing order.

  • tithonus49
     
    /* Paste your code here (You may delete these lines if not writing code) */
     
  • tithonus49

    An Aproach with STL sets..heres the cpp code,

     
    /*
    #include<cstdio>
    #include<set>
    using namespace std;
    
    int arr[1000005];
    multiset<int> s;
    multiset<int>:: iterator j,h;
    
    int func(int a[],int n,int k)
    {
        int i,x;
    	for(i=0;i<k;i++)
    	{
    		x=a[i];
    		s.insert(x);
    	}
    	j=s.end();
    	j--;
    	printf("%d ",*j);
    	
            for(i=k;i<n;i++)
    	{
    		s.erase(s.find(a[i-k]));
    		s.insert(a[i]);
    		h=s.end();
    		h--;
    		printf("%d ",*h);
    	}
    }
    
    int main()
    {
    	int n,k,i;
    	scanf("%d\n",&n);
    	for(i=0;i<n;i++)
    	scanf("%d",&arr[i]);
    	scanf("%d",&k);
    	func(arr,n,k);
    	return 0;
    }
    
     */
     
  • swagato mondal
     
    #include <stdio.h>
    
    int maxint(int a[],int s,int e)
    {
         int i,max=0;
         for (i = s; i < e; i++)
          if (max < a[i])
             max = a[i];
      return max;
    }
    
    void findmax(int arr[],int k,int n)
    {
         int i;
         
      for (i = 0; i< n; i++)
      {
          if(i+k-1<n)
           printf("%d ",maxint(arr,i,i+k));
         else 
                break;
      }
      
    
    }
     
    int main()
    {
      int arr[10] = {8,5,10,7,9,4,15,12,90,13};
      findmax(arr, 4, 10);
      getchar();
      return 0;
    }
    
     
  • redredp

    Your 3rd method is cool, but you made a little mistake at the line :

    std::deque<int> Qi(k);

    When you do that, the constructor “explicit deque(size_type count );” is called and allocate k elements. Each element is either default-constructed (if your deque is templated on a class), or filled with uninitialized values (if your dequeue is templated on scalar types, like here).

    Use this and it will be good :

    std::deque<int> Qi;

  • Ronny

    C code

     
    #include<stdio.h>
    
    int front=-1;
    int rear=-1;
    
    
    int isempty()
    {
        if(front==-1)
          return 1;
        else
         return 0;
    }
    
    void poprear()
    {
        rear--;
    
        if(rear==-1)
         front=-1;
    }
    
    void popfront()
    {
        front++;
        if(front==rear)
         {
             front=-1;
             rear=-1;
         }
    }
    
    void pushback(int dq[],int x)
    {
        dq[++rear]=x;
    
        if(rear==0)
         front=0;
    }
    
    void printmax(int arr[],int n,int k)
    {
    
        if (k<=0 || k>n)
            return;
    
        int dq[k];
        front=-1;
        rear=-1;
    
        int i;
        for(i=0;i<k;i++)
         {
             while (!isempty() && arr[i] >= arr[dq[rear]])
                    poprear();
    
             pushback(dq,i);
    
         }
    
    
        for(;i<n;i++)
         {
            printf("%d ",arr[dq[front]]);
    
            while(!isempty() && dq[front]<= i - k)
               popfront();
    
            while (front != -1 && arr[i] >= arr[dq[rear]])
                poprear();
    
            pushback(dq,i);
         }
    
         printf("%d ",arr[dq[front]]);
    }
    
    int main()
    {
        int arr[]={12,1,78,90,57,89,56};
        int n=sizeof(arr)/sizeof(arr[0]);
        int k=3;
    
        printmax(arr,n,k);
    
        return 0;
    }
    
    
     
    • Ronny

      @all
      what is wrong in the above c code

      it produces 78 90 90 90 56 as output
      but the output should be 78 90 90 90 89

      Please anyone help, I have coded in C (without using STL) according to the C++ version posted above

      • Ronny

        Just replace the popfront method by

        void popfront()
        {
        front++;
        if(front==rear+1)
        {
        front=-1;
        rear=-1;
        }
        }

        It works fine

  • crazy
     #include<stdio.h>
    int main()
    {
        int n,k,i,pos=0,max=0,r;
        scanf("%d",&n);
        int a[n];
        for(i=0;i<n;i++)
         scanf("%d",&a[i]);
        scanf("%d",&k);
        for(i=0;i<k;i++)
        {
            if(a[i]>max)
            {
                max=a[i];
                pos=i;
            }
        }
        printf("%d ",max);
        for(i=1;i<n-k+1;i++)
        {
            if(i==pos+1)
            {
                max=0;
                for(r=i;r<i+k;r++)
                {
                    if(a[r]>max)
                    {
                        max=a[r];
                        pos=r;
                    }
                }
            }
            else
            {
                if(a[i+k-1]>max)
                {
                    max=a[i+k-1];
                    pos=i+k-1;
                }
            }
            printf("%d ",max);
        }
        printf("\n");
        return 0;
    } 
  • Priyanshu

    A similar problem for practice is:

     
    /* The AC code for the above problem. */
    
    
    #include<iostream>
    #include<deque>
    #include<stdio.h>
    using namespace std;
    int a[1000006];
    int main()
    {
        int n,k,m,i,j;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        scanf("%d",&a[i]);
        scanf("%d",&k); //window
        deque<int> dq;
        for(i=0;i<k;i++)
        {
           // cout<<"hello\n";
            while(!dq.empty() && a[dq.back()]<=a[i])
            dq.pop_back();
            dq.push_back(i);
        }
       // cout<<dq.size()<<" \n";
        for(i=k;i<n;i++)
        {
           // cout<<"hello ";
            printf("%d ",a[dq.front()]);
            while(!dq.empty() && a[dq.back()]<=a[i])
            dq.pop_back();
            dq.push_back(i);
            while(!dq.empty() && i-dq.front()+1>k )
            dq.pop_front();
        }
        printf("%d",a[dq.front()]);
        return 0;
     
    }
     
     

    Happy Coding :)

  • Sreenivas Doosa

    The following code takes O(n) time with no extra space. Please check. This is based on sliding window concept.

     
    void printKMax(int arr[], int n, int k)
    {
    	// first find the max element of first K elements
        int max = INT_MIN;
    	for(int i = 0; i < k; i++) // This loops runs k times. Time complexity: O(k)
    	{
    		if(arr[i] > max)
    			max = arr[i];
    	}
    	printf("%d ", max); // printing the max of first k elements i.e. for index 0
    	
    	for(i = 1; i <= n - k; i++) // This loops runs n-k times. Time complexity: O(n-k)
        {
            if(arr[i + k - 1] > max)
    		{
    			max = arr[i + k - 1]
    		}
            
            printf("%d ", max);
        }
    }
     

    The overall complexity of the program is O(k) + O(n-k) = O(n)

    • Priyanka K

      incorrect

      • Sreenivas Doosa

        Yes Priyanka, I agree my solution does not work.

  • Rediff

    Can be solved with Min Heap in O(nlogk) = O(n).

    Simpler implementation.

    • Rediff

      Sorry, my mistake. Cant be done

      • codinggeek16

        It can be. Take another array to store the index in max heap. Max heap node will contains the index of elements only. Each time you go out of window, get the index in the heap and use upHeapify or downHeapify accordingly,

        • Actually there is no need for the Array, you can modify it in the existing array, and it’s better in the SB-BST

  • Akhil
     
    /* An O(n) approach using queues */
    /* Simple, straight-forward and easy */
    #include<stdio.h>
    
    void printMaxSub( int a[], int n, int k)
    {
        int q[n],f=0,r=0,i;
        q[r]=a[0];
        for(i=0;i<n;i++)
        {
            //delete smaller elements and insert new element in queue such that
            // queue from f to r contains elements in non decreasing order
            if(q[f]<a[i]) {q[r+1]=a[i];f=r=r+1;}
            else if(q[r]>=a[i]){q[++r]=a[i];}
            else
            {
                while(r>f && q[r]<a[i]) r--;
                q[++r]=a[i];
            }
            if(i>=k-1)
            {
                //delete element not in the subarray
                if(q[f]==a[i-k]) f++;
                //display the largest element
                printf("%d ",q[f]);
            }
        } 
    }
    int main()
    {
        int a[] = {1,2,3,1,4,5,2,3,6};
        int n = sizeof(a)/sizeof(a[0]);
        int k = 3;
        printMaxSub(a,n,k);
        getchar();
        return 0;
    }
    
     
    • Kartik

      It seems to be printing incorrect result for 6, 5, 4, 3, 2, 1.

      The output of following code is 6 6 6 6, but it should be 6 5 4 3. Please let me know if I missed anything.

       
      /* An O(n) approach using queues */
      /* Simple, straight-forward and easy */
      #include<stdio.h>
      
      void printMaxSub(int a[], int n, int k)
      {
          int q[n], f=0, r=0, i;
          q[r] = a[0];
          for (i=0; i<n; i++)
          {
              // delete smaller elements and insert new element in queue such that
              // queue from f to r contains elements in non decreasing order
              if (q[f] < a[i])
              {
                  q[r+1] = a[i];
                  f = r = r+1;
              }
              else if (q[r] >= a[i])
              {
                  q[++r] = a[i];
              }
              else
              {
                  while(r>f && q[r]<a[i])
                      r--;
                  q[++r]=a[i];
              }
              if (i >= k-1)
              {
                  //delete element not in the subarray
                  if (q[f]==a[i-k])
                      f++;
      
                  //display the largest element
                  printf("%d ",q[f]);
              }
          }
      }
      int main()
      {
          int a[] = {6, 5, 4, 3, 2, 1};
          int n = sizeof(a)/sizeof(a[0]);
          int k = 3;
          printMaxSub(a,n,k);
          getchar();
          return 0;
      }
      
       
  • amit

    following code just
    1) find the max value in first K elements
    2) thereafter for all windows it only checks for element greater than max

     
    int findMaxinSubArr( int * a,  int size, int k ){
    
    
    
        if(a==NULL){
    
            return -1;
        }
    
    
        printf(" size of the arrray is :%d and value of K : %d \n",size,k);
        if(k<=0 || k > size )
        {
            printf(" wrong value of K \n");
            return -1;
        }
    
        int max = 0 ;
    
        int i=0;
    
        for(i=0;i < k ; i++)
        {
            printf(" %d %d\n",a[i],max);
            if(a[i] > max)
            {
                max = a[i];
            }
        }
    
        printf("max value for the first %d elements is %d\n", k ,max);
        int j=0;
        for(j=1;j<size-2;j++){
    
            if(a[j+k-1] > max)
            {
                max = a[j+k-1];
    
            }
    
            printf(" Max value: %d\t",max);
            printf(" interval :%d - %d \n",j, j+k-1);
    
    
    
        }
    
        return 0;
    
    }
    
     
    • akki

      Your method will not work if array is sorted in decreasing order.

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • Aashish Barnwal

    A O( N ) approach

     
    void SlidingWindow( int arr[], int size, int k )
    {
            if ( k <= 0 || k > size )
                    return;
     
            int Q[ k ], f, r, i;
     
            f = r = -1;
            
            for( i = 0; i < k; ++i )
            {
                    while( f != -1 && arr[i] >= arr[ Q[r] ] )
                    {
                            r--;
                            if( r == -1 )
                                    f = -1;
                    }
     
                    Q[ ++r ] = i;
                    if( r == 0 )
                            f = 0;
            }
     
            for( ; i < size; ++i )
            {
                    printf( "%d ", arr[ Q[f] ] );
     
                    while( f != -1 && Q[f] <= i - k )
                    {
                            f++;
                            if( f == r )
                                    f = r = -1;
                    }
     
                    while( f != -1 && arr[i] >= arr[ Q[r] ] )
                    {
                            r--;
                            if( r == -1 )
                                    f = -1;
                    }       
     
                    Q[ ++r ] = i;
                    if( r == 0 )
                            f = 0;  
            }
            printf( "%d", arr[ Q[f] ] );
    }
     
    int main()
    {
            int arr[] = {1, 2, 3, 1, 4, 5, 2, 3, 6};//{8, 5, 10, 7, 9, 4, 15, 12, 90, 13};
            int size = sizeof( arr ) / sizeof( *arr );
     
            SlidingWindow( arr, size, 3 );
     
            return 0;
    }
     

    https://ideone.com/skDPu

    • Ronny

      @aashish
      Sir
      in the following module
      while( f != -1 && Q[f] <= i – k ) { f++; if( f == r ) f = r = -1; } by if(f==r+1) Then the code produces correct result. Anyways thanks for a wonderful approach. Kudos

  • bunty

    @geeks:
    In method 2:
    What if there are duplicates in the array ?

    Ex: If a[0] is very large element and it appears more than once, then while creating the BST, we have to keep the duplicates. This is because, this element’s appearances in its sub-array can be max element.
    – While deleting a[i], we must delete first appearing element (in array) of value same as a[i].

  • titan

    A very good solution and explanation using deque is given at
    http://www.leetcode.com/2011/01/sliding-window-maximum.html

    • Hong

      That solution is not O(n). Consider the case when all elements are sorted in decreasing order.

      • Apurvkagrawal

        true that!

  • Spock

    Here is the working code for the BST implementation of the problem.

     
    #include<stdio.h>
    #include<stdlib.h>
    
    struct node {
           int data;
           struct node *left;
           struct node *right;
    };
    
    struct node *newnode(int dat) {
           struct node *newone = malloc(sizeof(struct node));
           newone->left = NULL;
           newone->right = NULL;
           newone->data =  dat;
           return newone;
    }
    
    struct node *insert(struct node *root, int dat) {
           if(root == NULL) {
                   return newnode(dat);
           }
           if(dat <= root->data) {
                  root->left = insert(root->left, dat);
           }
           else if(dat > root->data) {
                root->right = insert(root->right,dat);
           }
           return root;
    }
    
    struct node *findmin(struct node *root) {
           if(root -> left == NULL || root == NULL) {
                   return root;
           }
           return findmin(root->left);
    }
    
    struct node *deletenode(struct node *root, int x) {
           struct node *temp;
           if(x > root->data) {
                root->right = deletenode(root->right, x);
           }
           else if(x < root->data) {
                root->left = deletenode(root->left,x);
           }
           else {
                if(root->right && root->left) {
                               temp = findmin(root->right);
                               root->data = temp->data;
                               root->right = deletenode(root->right, root->data);
                }
                else if(root->right == NULL) {
                     root = root->left;
                }
                else {
                    root = root->right;
                }
           }
           return root;
    }
    
    int printmax(struct node *root) {
        if(root == NULL || root->right == NULL) {
                return (root->data);
        }
        return printmax(root->right);
    }
    
    int main() {
        int i;
        struct node *root = NULL;
        int n,k;
        printf("Enter the total number of numbers you want to insert in the array\n");
        scanf("%d", &n);
        int a[n];
        printf("Enter the numbers\n");
        for(i = 0; i < n; i++) {
              int x;
              scanf("%d", &x);
              a[i] = x;
        }
        printf("Enter the value of k\n");
        scanf("%d", &k);
        for(i = 0; i < k; i++) {
              root = insert(root,a[i]);
        }
        for(i = 0; i < (n-k); i++) {
              printf("%d ", printmax(root));
              root = deletenode(root, a[i]);
              root = insert(root,a[i+k]);
        }
        printf("%d ", printmax(root));
        printf("\n");
        system("pause");
        return 0;
    }
    
     
  • joker

    @ admin : BST is an over kill for this problem.
    lots of other solutions possible.
    1) segment tree can be used
    2) this one also nice solution.[plz include it.]
    http://shashank7s.blogspot.in/2011/06/given-array-and-integer-k-find-maximum.html

    • andrew

      @ Joker , yeah i liked solution given in link you provided from Cracking The Code

      Admin , correct the reference !

  • Anil Arya

    //here O(n) solution

    #include
    #define max 1000001
    int f[max];
    int arr[max];
    int b[max];

    int maximum(int *x,int *y)
    {
    return (*x>*y)?(*x):(*y);
    }
    int main()
    {
    int n,i,j,k;
    scanf(“%d”,&n);
    for(i=1;i<=n;i++)
    scanf("%d",&arr[i]);

    scanf("%d",&k);
    f[1]=arr[1];

    for(i=2;in-m;i–)
    {
    b[i]=maximum(&b[i+1],&arr[i]);
    }

    b[n-m]=arr[n-m];
    for(i=n-m-1;i>=1;i–)
    {

    if(i%k==0)
    {
    b[i]=arr[i];

    // i–;
    continue;
    }
    b[i]=maximum(&b[i+1],&arr[i]);

    }

    for(i=1;i<=n-k+1;i++)
    {

    printf("%d ",maximum(&b[i],&f[i+k-1]));
    }

    printf("\n");

    return 0;
    }

  • laddoo

    Guyz, I wrote this code..find any bug,if there..

     
    #include<stdio.h>
    #include<conio.h>
     
    void findKthMax(int arr[], int n, int k)
    {
        int i,j, max=arr[0],index1=0,index2=0,nextmax=arr[0];
     
        for (i = 1; i < k; i++)
        {
            if (arr[i] > max)
            {
    	       nextmax=max;
    	       index2=index1;
                   max = arr[i];
                   index1=i;
            }
    	else if (arr[i] > nextmax)
            {
                   nextmax = arr[i];
                   index2=i;
            }
        }
        printf("%d ", max);
        for (i = k; i <= n-1; i++)
        {
            if(index1!=i-k)
            {
                                    if (arr[i] > max)
                                    {
                                     nextmax=max;
                                     max = arr[i];
                                     printf("%d ", max);
                                    }
                                    else
                                    {
                                                printf("%d ", max);
                                                if (arr[i] > nextmax)
                                                {
                                                 nextmax = arr[i];
                                                }
                                                else if(index2==n-k)
                                                {
                                                     nextmax=arr[i];
                                                }
                                    }
            }
    	    else
            {
    				                if (arr[i] > nextmax)
                                    {
                                     max = arr[i];
                                     printf("%d ", max);
                                    }
                                    else
                                    {
                                        max=nextmax;
                                        printf("%d ", max);
                                        nextmax=arr[i];
                                    }
            }
        }
    }
     
    int main()
    {
        int arr[] = {9,10,8,7,6,5,4,3,2,1};
        int n = sizeof(arr)/sizeof(arr[0]);
        int k = 4;
        findKthMax(arr, n, k);
        getch();
        return 0;
    }
    
     

    Time Complexity : O(n)

    • laddoo

      Sry,My mistake..the code isn’t working properly,
      I’ll update later

  • prabhatlamba
     
    #include<stdio.h>
    #include<conio.h>
    #define max 100
    void main()
    {
    	clrscr();
    	int arr[max],k,n,maxi,j=0;
    	printf("enter the no. of values of an array: ");
    	scanf("%d",&n);
    	for (int l=0;l<n;l++)
    	scanf("%d",&arr[l]);
    
    	maxi=arr[0];
    	printf("\nenter the max lenght of array size: ");
    	scanf("%d",&k);
    
    	for(int i=j;i<k+j,i<n;i++)
    	{
    		if(arr[i]>maxi)
    		maxi=arr[i];
    
    		if(i==k+j-1)
    		{
    			j++;
    			printf("\nmaximum: %d",maxi);
    		}
    	}
    
    getch();
    }
    
     
    • what if the maximum for 1st go will be the first element..it will always print the overall max..clearly wrong solution

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • Ravi

    Modified data structure and heap

     
    #include <stdio.h>
    #include <stdlib.h>
    
    #define PARENT(i) (i - 1) / 2
    #define LEFT(i) 2*i + 1
    #define RIGHT(i) 2*i + 2
    #define SWAP(A,i,j) struct node *p = A[i]; A[i] = A[j]; A[j] = p; A[i]->heap_index = i; A[j]->heap_index = j;
    
    struct node {
    	int val;
    	int heap_index;
    	struct node *next;
    };
    
    void max_heapify(struct node *heap[],int i, int heapsize)
    {
    	int l = LEFT(i);
    	int r = RIGHT(i);
    	int max_index = i;
    	if (l < heapsize && heap[l]->val > heap[max_index]->val)
    		max_index = l;
    		
    	if (r < heapsize && heap[r]->val > heap[max_index]->val)
    		max_index = r;
    
    	if (max_index == i) 
    		return;
    	{
    		SWAP(heap, i, max_index);
    	}
    	max_heapify(heap, max_index, heapsize);
    }
    
    void build_max_heap(struct node *heap[], int heapsize)
    {
    	int i;
    	for (i = heapsize / 2 - 1; i >= 0; i--)
    		max_heapify(heap, i, heapsize);
    }
    
    void print(struct node *n[], int len)
    {
    	int i;
    	printf("[");
    
    	for (i = 0; i < len; i++) 
    		printf((i == len - 1) ? "%d]\n" : "%d, ", n[i]->val);
    }
    void insert(struct node *sub_set[], int j)
    {
    	while (j != 0) {
    		if (sub_set[j]->val > sub_set[PARENT(j)]->val) {
    			SWAP(sub_set, j, PARENT(j));
    			j = PARENT(j);
    		}
    		else
    			break;
    	}
    }
    
    
    int main()
    {
    	int set[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13};
    	int k = 5;
    	struct node *head = (struct node *) malloc(sizeof(struct node));
    	int i;
    	int temp;
    	int j;
    	struct node *tail;
    	tail = head;
    	for (i = 0; i < k; i++) {
    		tail->val = set[i];
    		tail->next = (struct node *)malloc(sizeof(struct node));
    		tail = tail->next;
    	}
    	struct node *sub_set[k];
    	struct node *t = head;
    	for (i = 0; i < k; i++) {
    		sub_set[i] = t;
    		t->heap_index = i;
    		t = t->next;
    	}
    	build_max_heap(sub_set, k);
    	for (i = k; i <= sizeof(set) / sizeof(int); i++) {
    		printf("%d\n", sub_set[0]->val);
    		temp = head->heap_index;
    		SWAP(sub_set, temp, k - 1);
    		max_heapify(sub_set, temp, k - 1);
    		t = head;
    		head = head->next;
    		free(t);
    		tail->val = set[i];
    		tail->heap_index = k - 1;
    		tail->next = (struct node *)malloc(sizeof(struct node));
    		sub_set[k - 1] = tail;
    		tail = tail->next;
    		insert(sub_set, k - 1);
    	}
    }
    
     
    • kartik

      @Ravi: Thanks for sharing the code. Could you please add few word about the logic. Thanks!

      • Ravi

        Hi,

        –Create a linked list of first k element of input with a pointer of head and tail. Each node will contain a integer values from input, and a index which will tell where this node is at the heap, and a pointer to next node.

        –create a max heap with these nodes, based on value stores in it.

        –For i = k to size of input
        print the first element of heap.
        remove the head of the list, also from the
        heap.
        append the tail with next element in input.
        add this to heap.
        end

        Time in making heap = O(k), making linked list = O(k), removal takes O(logk), adding takes O(logk). Adding and removing happens O(n) times..
        total complexity – 2*O(k) + 2*n*O(logk), which is
        O(nlogk)

        • codez

          @Ravi: i hv a doubt.plz correct me if wrong
          suppose we have an array as give:
          10 4 8 6 7 1 2 8
          k=3;
          now according to ur algo
          -10,4,8 in heap with first elemnt h[0]=10;
          -then prnt,remove 10 ,then heap is 4 8 6, h[0]=8
          -prnt/rem 8,so next heap will be 4,6,7
          but it shuld be 8,6,7. since subarrys are contiguous

          plz correct me , if m considering it wrong way

           
          /* Paste your code here (You may delete these lines if not writing code) */
           
  • Andrew Moor

    @Imran, this can be easely solved, we just watch two maximum values, and if the largest one dissapear, we compare next value with the second one

    internal static string MaxOfAllSubbarraysOfSizeK(int[] a, int k)
    {
    if(a == null || a.Length < 1)
    throw new Exception("Array is empty");
    if(k < 1 || k > a.Length)
    throw new Exception("SubArray size is out of range");
    if (a.Length == 1)
    return string.Format("{0} ", a[0]);

    var output = new StringBuilder();
    const string format = "{0} ";
    var maxFirst = a[0] > a[1] ? a[0] : a[1];
    var maxSecond = a[0] > a[1] ? a[1] : a[0];

    //Search for two maximum values
    for (var i = 2; i < k; i++)
    {
    if (a[i] > maxFirst)
    {
    maxSecond = maxFirst;
    maxFirst = a[i];
    }
    else
    {
    if (a[i] > maxSecond)
    {
    maxSecond = a[i];
    }
    }
    }
    output.AppendFormat(format, maxFirst);

    for (var i = k; i < a.Length; i++)
    {
    //If maximum number disappear from subarray we
    //compare next value with second maximum
    if (a[i – k] == maxFirst)
    {
    maxFirst = maxSecond;
    }
    if (a[i] > maxFirst)
    {
    maxFirst = a[i];
    }
    else
    {
    maxSecond = a[i];
    }
    output.AppendFormat(format, maxFirst);
    }

    return output.ToString();
    }

    So, we have O(n) complexity

    • Anuj Bansal

      What if both the maximum and second maximum value disappear from the array? With what value will you compare afterwards?

      • asahu

        what if the next k elements are less than last and 2nd last max value. e.g.
        8,9,10,11,3,1,2,4

         
        /* Paste your code here (You may delete these lines if not writing code) */
         
        • bhavesh

          and with post of asahu k=3 and try to evaluate that

  • Andrew Moor

    @Imran, this can be easely solved, we just watch two maximum values, and if the largest one dissapear, we compare next value with the second one

    internal static string MaxOfAllSubbarraysOfSizeK(int[] a, int k)
    {
    if(a == null || a.Length < 1)
    throw new Exception("Array is empty");
    if(k < 1 || k > a.Length)
    throw new Exception("SubArray size is out of range");
    if (a.Length == 1)
    return string.Format("{0} ", a[0]);

    var output = new StringBuilder();
    const string format = "{0} ";
    var maxFirst = a[0] > a[1] ? a[0] : a[1];
    var maxSecond = a[0] > a[1] ? a[1] : a[0];

    //Search for two maximum values
    for (var i = 2; i < k; i++)
    {
    if (a[i] > maxFirst)
    {
    maxSecond = maxFirst;
    maxFirst = a[i];
    }
    else
    {
    if (a[i] > maxSecond)
    {
    maxSecond = a[i];
    }
    }
    }
    output.AppendFormat(format, maxFirst);

    for (var i = k; i < a.Length; i++)
    {
    //If maximum number disappear from subarray we
    //compare next value with second maximum
    if (a[i – k] == maxFirst)
    {
    maxFirst = maxSecond;
    }
    if (a[i] > maxFirst)
    {
    maxFirst = a[i];
    }
    else
    {
    maxSecond = a[i];
    }
    output.AppendFormat(format, maxFirst);
    }

    return output.ToString();
    }

  • #include
    #define INF 10000
    #define max(x,y) x>y?x:y
    main()
    {
    int a[]={10,-12,13,16,7,21,-10,56,67};
    int sum1=0,sum2=0;
    int i;
    for(i=0;i<9;i++)
    {
    sum1=max((sum1+a[i]),0);
    sum2=max(sum1,sum2);
    }
    printf("Max sum is: %d",sum2);
    }

  • Munmun

    I would like to suggest an O(n) solution for the same.
    Allocate 2 arrays of size n each.
    int max[n];
    int max_index[n];
    int arr[n] = {1,2,3,1,4,5,2,3,6};
    int k =3;
    int i,maxValue=0;
    max[0] =
    for(i=1;i ){
    max[i]=arr[i]

    }
    }

    }

  • Shreyansh
     #include<stdio.h>
    #include<conio.h>
    int main()
    {
        int a[]={1,2,3,1,4,5,2,3,6};
        int i,j,k=0,max;
        for(j=0;k<=6&&j<=2;j++)
        {
                     if(j==0)
                     {
                             max=a[k+j];
                     }
                     else if(max<a[k+j])
                     {
                          max=a[k+j];
                     }
                     if(j==2)
                     {
                             printf("%d",max);
                             k++;
                             j=-1;
                     }
        }
        getch();
        return 0;
    }    
     
    • nikhil

      complexity is still O(n*k)..what is the improvement?????????

  • Shreyansh

    #include
    #include
    int main()
    {
    int a[]={1,2,3,1,4,5,2,3,6};
    int i,j,k=0,max;
    for(j=0;k<=6&&j<=2;j++)
    {
    if(j==0)
    {
    max=a[k+j];
    }
    else if(max<a[k+j])
    {
    max=a[k+j];
    }
    if(j==2)
    {
    printf("%d",max);
    k++;
    j=-1;
    }
    }
    getch();
    return 0;
    }

  • Ayush

    In the heap algorithm, rather than deleting a node and adding the new one, we could replace the value of node to be deleted with value of node to be added.Heapify() the heap next in logk. Thus O(k+(n-k+1)logk)

  • Mohan

    Below code work’s in O(n)

    public void printMaxFromSubArray(int[] arr,int k){
    int max = 0;
    if(arr.length < k){
    System.out.println("Array lenght is less than the sub array size");
    return;
    }
    for(int i=0;i<arr.length;i++){
    if(max < arr[i]){
    max = arr[i];
    }
    if(i >= k-1){
    System.out.print(max);
    }
    }
    }

    • Leo

      @Mohan It does not work. Try it for following array
      {6, 2, 3, 1, 4, 5, 2, 3, 6}

  • @all Its Nothing But Sliding Window Problem in which we have to find Maximum in each sub-windoww of size K

  • Using Max Heap:
    1>create a max heap of size k:max_heap[3] and insert arr[0],arr[1],arr[2];
    2>for(i=0;i<n-k;i++)
    {print max_heap[0];
    delete_heap(arr[i];
    insert_heap(arr[i+k])
    }

    ;;;;;;;;;;;;;;;;;;
    complexity=O(klgk)+O((n-k)*lg(k))
    == O(nlgk)

    • sankalp

      The max heap does not support efficient deletion and can be O(n) in worst case . Also , to delete a node .You need to make sure that the heap structure is maintained and the delete procedure will make the heap at the deleted element , call a heapify (making a senitel of infinity i suppose )
      Hence , this will take O(n+log n) for every elemenent deleted

      Thus , total time complexity : O(n-k*(n+log n))) which is O(n^2)

  • Gopal

    O(n) Solution

     
    public static void printKMax(int[] array,int k){
    	if(array == null || array.length == 0)
    		return;
    		
    	int max = Integer.MIN_VALUE;
    		
    	for(int i=0;i < k && i<array.length;i++){
    		if(max < array[i]){
    			max = array[i];
    		}
    	}
    	System.out.print(max + " ");
    	for(int i=k;i < array.length;i++){
    		if(max < array[i]){
    			max = array[i];
    		} 
    	        System.out.print(max + " ");
    	}
    }
     
    • nicks

      it won’t work as discussed earlier solution will not work for a list which is in descending order. 50, 40, 30, 20, 10 k=2

    • nicks

      if anyone has the code of method 2(BST)…then please share !!

  • DeadCoder
     
    int main()
    {
    	int a[]={8, 5, 10, 7, 9, 4, 15, 12, 90, 13};
    	int n = 10;			//n elements in array
    	int k = 4; 			//Size of subarray 
    	
    	
    	int i, j, t, max;
    	
    	i=0;
    	j=k;
    	max=0x80000000;
    	
    	for (t = 0; t < k ; t++ )
    	{
    		if(max < a[t])
    		 max=a[t];	
    	}
    	printf("%dt",max);
    	
    	//Now i=0, j=k, max= maximum of first k elements
    	while(j=max)
    		{
    			max=a[j];
    			i++;
    			j++;
    		}
    		else if(a[i]==max)
    		{
    			i++;
    			j++;
    			for( t=i; t<j ; t++)
    			{
    				if(max < a[t])
    				 max=a[t];				
    			}
    			
    		}	
    		else
    		{
    			i++;
    			j++;
    		}
    		
    		printf("%dt",max);	
    	}
    	
    	return 0;
    }
     
  • Praveen raj
     
    //correct code
    
    #include<stdio.h>
    void main()
    {
      int i, k, n, max=0, previous=0, a[20];
      scanf("%d%d",&k,&n);
      for (i=0; i<n; i++)
        scanf("%d",&a[i]);
      for (i=0; i<k; i++)
        previous = previous+a[i];
      max = previous;
      for(i=0;i<=n-k-1;i++)
      {
          previous=previous-a[i]+a[i+k];
          if(previous>max)
             max=previous;
      }
      printf("%d",max);
    }
     
    • Using Max Heap:
      1>create a max heap of size k:max_heap[3] and insert arr[0],arr[1],arr[2];
      2>for(i=0;i<n-k;i++)
      {print max_heap[0];
      delete_heap(arr[i];
      insert_heap(arr[i+k])
      }

      ;;;;;;;;;;;;;;;;;;
      complexity=O(klgk)+O((n-k)*lg(k))
      == O(nlgk)

      • shanky

        in step 1 after creating max heap arr[0]=3 arr[1]=2 arr[2]=1 .now in 2nd statement of for loop u r deleting arr[0] ie 3 bt actually we want to delete 1 ie arr[2].crect me if i am wrng

  • could we do it like this:

     int max = findMax(array, 0, k-1);
    int i=k;
    while(i<length)
    {
    max = max>array[i]?max:array[i];
    i++
    }
     

    the idea is that each time we are shifting the array to right by one, so just comparing the list element to the max of previous array of size k should work.
    please let me know if it wont work.

    • looks like it wont work if the max of the previous subarray was the first element of that subarray. but i think it could be taken care of in the same code.

    • Nitish
       
      #include <stdio.h>
      
      void maxk(int *arr,int k,int n);
      
      int main()
      {
      	int arr[]={8, 5, 10, 7, 9, 4, 15, 12, 90, 13};
      	maxk(arr,3,sizeof(arr)/sizeof(int));
      }
      
      void maxk(int arr[],int k,int n)
      {
      	int max,i;
      	max= *arr;
      	for(i=0;i<n;i++)
      	{
      		if(max1)
      			k--;
      		else
      			printf("%d",max);
      	}
      }
       

      It is absolutely fine.

  • ella

    The double-ended queue
    the largest element in the subarray
    would always appear in the front of the queue
    run time complexity of O(n).

    • Dumanshu

      @ella: could you plz elaborate.

  • Shiraj Pokharel

    how about using a max heap and an auxillary array that stores index of the first element in window(the one to be replaced next).
    Heapify after each insertion and the top element is the output per window.

    • Sandeep

      @Shiraj Pokharel:
      This looks another good approach. When we replace a node, we have to make sure that the subtree with replaced node is heapified and its ancestors are also heapified. We will analyze this further and add it to the original post.

      • bunty

        @geeks, Sandeep:
        – Max heap can solve the purpose along with a auxiliary variable to save the index of first element of the sub-array.
        The algo will be same as METHOD2.
        1- Build MaxHeap (O(k)). Keep track of a[first] in int aux.
        2- Print Root
        3- Delete org a[i] from MaxHeap. This can be done by replacing MaxHeap[aux] by MaxHeap[last].
        Now do heapify MaxHeap. Only heapify wrt to children would be required. (I need to check).
        3- Now add a[first+k] as last element in MaxHeap and do heapify again.

        Perhaps, step 3 can have both heapifyWRTparents() and heapifyWRTchildren() and it should solve the purpose.

        • Sandeep

          @bunty: The idea looks good. We will take another look at it and add it to the original post. Thanks!!

          • Sandeep

            @bunty: I took another look at your approach and tried to implement it. The problem is, how to update aux after first deletion.

    • rajcools

      why do we need auxiliary array , we can do this with given array and a max heap only….

    • rajcools

      @someone who has disliked shivraj’s comment.Reason?…. what happened cant u tolerate others giving good ideas when u r not able to find one

      • RF

        max heap will give same complexity (n log(k))…eg:(let start indexing frm 1)
        2341111 window size:3 heaps:(heap/top)(234/4)index:3
        then (2341/4) index:3
        then (23411/4)index:3
        now u will delete 4 since size f window is 3
        then (23111/3)wrong output!!!
        i want to convey that every time you have to delete elem…searching and deleting is log(k)and hence n(logk)…M I wrong??

        • Ankit Mehta

          but easier to implement than self balancing BST :)

  • Imran Amjad

    This can be done on O(n) time by finding max in first k elements. Then match max for each index of array after k elements. Here is the code..

    public static void printMaxOfSubArray(int[] array, int k)
    {
    if(array == null || array.length <1)
    throw new IllegalArgumentException("Array is empty");
    if(k < 1 || k > array.length)
    throw new IllegalArgumentException("SubArray size is out of range");

    if(array.length ==1)
    System.out.print(array[0]);

    int max = array[0];
    for(int i=1; i<array.length; i++)
    {
    if(max < array[i])
    {
    max = array[i];
    }
    //only display max when k elements are checked
    if(i+1 >= k) System.out.print(max + ", ");
    }
    }

    • Imran Amjad

      That was quite a hasty work. my solution will not work for a list which is in descending order. 50, 40, 30, 20, 10 k=2