# Replace every array element with maximum of K next and K previous elements

• Difficulty Level : Hard
• Last Updated : 04 Apr, 2022

Given an array arr, the task is to replace each array element by the maximum of K next and K previous elements.

Example:

Input: arr[] = {12, 5, 3, 9, 21, 36, 17}, K=2
Output: 5 12 21 36 36 21 36

Input: arr[] = { 13, 21, 19}, K=1
Output: 21, 19, 21

Naive Approach: Follow the below steps to solve this problem:

1. Traverse the array from i=0 to i<N and for each element:
• Run another loop from j=i-K to j<=i+K, and change arr[i] to the maximum of K next and K previous elements.
2. Print the array after the above loop ends.

Below is the implementation of the above approach:

## C++

 // C++ program for the above approach   #include #include #include using namespace std;   // Function to update the array // arr[i] = maximum of prev K and next K elements. void updateArray(int arr[], int N, int K) {       int start, end;     for (int i = 0; i < N; i++) {         int mx = INT_MIN;           // Start limit is max(i-K, 0)         start = max(i - K, 0);           // End limit in min(i+K, N-1)         end = min(i + K, N - 1);         for (int j = start; j <= end; j++) {               // Skipping the current element             if (j == i) {                 continue;             }             mx = max(arr[j], mx);         }           cout << mx << ' ';     } }   // Driver Code int main() {     int arr[] = { 12, 5, 3, 9, 21, 36, 17 };     int N = sizeof(arr) / sizeof(arr[0]);     int K = 2;       updateArray(arr, N, K); }

## Java

 // Java program for the above approach import java.util.*;   class GFG{       // Function to update the array arr[i] = maximum // of prev K and next K elements. static void updateArray(int arr[], int N, int K) {     int start, end;     for(int i = 0; i < N; i++)     {         int mx = Integer.MIN_VALUE;           // Start limit is max(i-K, 0)         start = Math.max(i - K, 0);           // End limit in min(i+K, N-1)         end = Math.min(i + K, N - 1);         for(int j = start; j <= end; j++)         {                           // Skipping the current element             if (j == i)             {                 continue;             }             mx = Math.max(arr[j], mx);         }         System.out.print(mx + " ");     } }   // Driver Code public static void main(String args[]) {     int arr[] = { 12, 5, 3, 9, 21, 36, 17 };     int N = arr.length;     int K = 2;       updateArray(arr, N, K); } }   // This code is contributed by Samim Hossain Mondal.

## Python3

 # python3 program for the above approach INT_MIN = -2147483648   # Function to update the array # arr[i] = maximum of prev K and next K elements. def updateArray(arr, N, K):       for i in range(0, N):         mx = INT_MIN           # Start limit is max(i-K, 0)         start = max(i - K, 0)           # End limit in min(i+K, N-1)         end = min(i + K, N - 1)         for j in range(start, end + 1):               # Skipping the current element             if (j == i):                 continue             mx = max(arr[j], mx)         print(mx, end=" ")   # Driver Code if __name__ == "__main__":       arr = [12, 5, 3, 9, 21, 36, 17]     N = len(arr)     K = 2       updateArray(arr, N, K)   # This code is contributed by rakeshsahni

## C#

 // C# program for the above approach using System; class GFG {     // Function to update the array arr[i] = maximum   // of prev K and next K elements.   static void updateArray(int[] arr, int N, int K)   {     int start, end;     for (int i = 0; i < N; i++)     {       int mx = int.MinValue;         // Start limit is max(i-K, 0)       start = Math.Max(i - K, 0);         // End limit in min(i+K, N-1)       end = Math.Min(i + K, N - 1);       for (int j = start; j <= end; j++)       {           // Skipping the current element         if (j == i)         {           continue;         }         mx = Math.Max(arr[j], mx);       }       Console.Write(mx + " ");     }   }     // Driver Code   public static void Main()   {     int[] arr = { 12, 5, 3, 9, 21, 36, 17 };     int N = arr.Length;     int K = 2;       updateArray(arr, N, K);   } }   // This code is contributed by Saurabh Jaiswal

## Javascript



Output

5 12 21 36 36 21 36

Time Complexity: O(N*N)
Auxiliary Space: O(1)

Efficient Approach: A segment tree can be used to solve this problem. So, construct a range max segment tree, where:

• Leaf Nodes are the elements of the input array.
• Each internal node represents the maximum of all of its children.

Now, after building the segment tree, find the maximum from (i-K) to (i-1), say left and the maximum of (i+1) to (i+K), say right using query on this segment tree. Replace arr[i] with the maximum of left and right.

Below is the implementation of the above approach:

## C++

 // C++ code for the above approach   #define MAXN 500001   #include using namespace std;   // Function to build the tree void buildTree(vector& arr,                vector& tree, int s,                int e, int index) {       // Leaf Node     if (s == e) {         tree[index] = arr[s];         return;     }       // Finding mid     int mid = (s + e) / 2;       buildTree(arr, tree, s,               mid, 2 * index + 1);     buildTree(arr, tree, mid + 1,               e, 2 * index + 2);       // Updating current node     // by the maximum of its children     tree[index]         = max(tree[2 * index + 1],               tree[2 * index + 2]); }   // Function to find the maximum // element in a given range int query(vector& tree, int s,           int e, int index, int l,           int r) {       if (l > e or r < s) {         return INT_MIN;     }       if (l <= s and r >= e) {         return tree[index];     }       int mid = (s + e) / 2;       int left = query(tree, s, mid,                      2 * index + 1, l, r);     int right         = query(tree, mid + 1, e,                 2 * index + 2, l, r);       return max(left, right); }   // Function to replace each array element by // the maximum of K next and K previous elements void updateArray(vector& arr, int K) {       // To store the segment tree     vector tree(MAXN);       int N = arr.size();     buildTree(arr, tree, 0, N - 1, 0);       for (int i = 0; i < N; ++i) {         // For 0th index only find         // the maximum out of 1 to i+K         if (i == 0) {             cout << query(tree, 0, N - 1, 0, 1,                           min(i + K, N - 1))                  << ' ';             continue;         }           // For (N-1)th index only find         // the maximum out of 0 to (N-2)         if (i == N - 1) {             cout << query(tree, 0, N - 1,                           0, max(0, i - K),                           N - 2);             continue;         }           // Maximum from (i-K) to (i-1)         int left = query(tree, 0, N - 1,                          0, max(i - K, 0),                          i - 1);           // Maximum from (i+1) to (i+K)         int right = query(tree, 0,                           N - 1, 0, i + 1,                           min(i + K, N - 1));           cout << max(left, right) << ' ';     } }   // Driver Code int main() {     vector arr = { 12, 5, 3, 9,                         21, 36, 17 };     int K = 2;       updateArray(arr, K); }

## Java

 // Java code for the above approach import java.io.*; class GFG {     static int MAXN = 500001;     // Function to build the tree   static void buildTree(int[] arr, int[] tree, int s,                         int e, int index)   {       // Leaf Node     if (s == e) {       tree[index] = arr[s];       return;     }       // Finding mid     int mid = (s + e) / 2;       buildTree(arr, tree, s, mid, 2 * index + 1);     buildTree(arr, tree, mid + 1, e, 2 * index + 2);       // Updating current node     // by the maximum of its children     tree[index] = Math.max(tree[2 * index + 1],                            tree[2 * index + 2]);   }     // Function to find the maximum   // element in a given range   static int query(int[] tree, int s, int e, int index,                    int l, int r)   {       if (l > e || r < s) {       return Integer.MIN_VALUE;     }       if (l <= s && r >= e) {       return tree[index];     }       int mid = (s + e) / 2;       int left = query(tree, s, mid, 2 * index + 1, l, r);     int right       = query(tree, mid + 1, e, 2 * index + 2, l, r);       return Math.max(left, right);   }     // Function to replace each array element by   // the maximum of K next and K previous elements   static void updateArray(int[] arr, int K)   {       // To store the segment tree     int[] tree = new int[MAXN];       int N = arr.length;     buildTree(arr, tree, 0, N - 1, 0);       for (int i = 0; i < N; ++i)     {         // For 0th index only find       // the maximum out of 1 to i+K       if (i == 0) {         System.out.print(query(tree, 0, N - 1, 0, 1,                                Math.min(i + K, N - 1))                          + " ");         continue;       }         // For (N-1)th index only find       // the maximum out of 0 to (N-2)       if (i == N - 1) {         System.out.println(query(tree, 0, N - 1, 0,                                  Math.max(0, i - K),                                  N - 2));         continue;       }         // Maximum from (i-K) to (i-1)       int left = query(tree, 0, N - 1, 0,                        Math.max(i - K, 0), i - 1);         // Maximum from (i+1) to (i+K)       int right = query(tree, 0, N - 1, 0, i + 1,                         Math.min(i + K, N - 1));         System.out.print(Math.max(left, right) + " ");     }   }     // Driver Code   public static void main (String[] args)   {     int[] arr = { 12, 5, 3, 9, 21, 36, 17 };     int K = 2;       updateArray(arr, K);   } }   // This code is contributed by Shubham Singh.

## Python3

 # Python code for the above approach import sys   MAXN = 500001   # Function to build the tree def buildTree(arr, tree, s, e, index):       # Leaf Node     if (s == e):         tree[index] = arr[s]         return       # Finding mid     mid = (s + e) // 2       buildTree(arr, tree, s, mid, 2 * index + 1)     buildTree(arr, tree, mid + 1, e, 2 * index + 2)       # Updating current node     # by the maximum of its children     tree[index] = max(tree[2 * index + 1], tree[2 * index + 2])   # Function to find the maximum # element in a given range def query(tree, s, e, index, l, r):       if (l > e or r < s):         return -sys.maxsize -1       if (l <= s and r >= e):         return tree[index]       mid = (s + e) // 2       left = query(tree, s, mid,2 * index + 1, l, r)     right = query(tree, mid + 1, e, 2 * index + 2, l, r)       return max(left, right)   # Function to replace each array element by # the maximum of K next and K previous elements def updateArray(arr, K):       global MAXN     # To store the segment tree     tree = [0 for i in range(MAXN)]       N = len(arr)     buildTree(arr, tree, 0, N - 1, 0)       for i in range(N):         # For 0th index only find         # the maximum out of 1 to i+K         if (i == 0):             print(query(tree, 0, N - 1, 0, 1, min(i + K, N - 1)),end = ' ')             continue           # For (N-1)th index only find         # the maximum out of 0 to (N-2)         if (i == N - 1):             print(query(tree, 0, N - 1, 0, max(0, i - K), N - 2))             continue           # Maximum from (i-K) to (i-1)         left = query(tree, 0, N - 1, 0, max(i - K, 0), i - 1)           # Maximum from (i+1) to (i+K)         right = query(tree, 0, N - 1, 0, i + 1, min(i + K, N - 1))           print(max(left, right),end = ' ')   # Driver Code arr = [12, 5, 3, 9, 21, 36, 17] K = 2   updateArray(arr, K)   # This code is contributed by shinjanpatra

## C#

 // C# code for the above approach using System; class GFG {     static int MAXN = 500001;     // Function to build the tree   static void buildTree(int[] arr, int[] tree, int s,                         int e, int index)   {       // Leaf Node     if (s == e) {       tree[index] = arr[s];       return;     }       // Finding mid     int mid = (s + e) / 2;       buildTree(arr, tree, s, mid, 2 * index + 1);     buildTree(arr, tree, mid + 1, e, 2 * index + 2);       // Updating current node     // by the maximum of its children     tree[index] = Math.Max(tree[2 * index + 1],                            tree[2 * index + 2]);   }     // Function to find the maximum   // element in a given range   static int query(int[] tree, int s, int e, int index,                    int l, int r)   {       if (l > e || r < s) {       return Int32.MinValue;     }       if (l <= s && r >= e) {       return tree[index];     }       int mid = (s + e) / 2;       int left = query(tree, s, mid, 2 * index + 1, l, r);     int right       = query(tree, mid + 1, e, 2 * index + 2, l, r);       return Math.Max(left, right);   }     // Function to replace each array element by   // the maximum of K next and K previous elements   static void updateArray(int[] arr, int K)   {       // To store the segment tree     int[] tree = new int[MAXN];       int N = arr.Length;     buildTree(arr, tree, 0, N - 1, 0);       for (int i = 0; i < N; ++i) {       // For 0th index only find       // the maximum out of 1 to i+K       if (i == 0) {         Console.Write(query(tree, 0, N - 1, 0, 1,                             Math.Min(i + K, N - 1))                       + " ");         continue;       }         // For (N-1)th index only find       // the maximum out of 0 to (N-2)       if (i == N - 1) {         Console.Write(query(tree, 0, N - 1, 0,                             Math.Max(0, i - K),                             N - 2));         continue;       }         // Maximum from (i-K) to (i-1)       int left = query(tree, 0, N - 1, 0,                        Math.Max(i - K, 0), i - 1);         // Maximum from (i+1) to (i+K)       int right = query(tree, 0, N - 1, 0, i + 1,                         Math.Min(i + K, N - 1));         Console.Write(Math.Max(left, right) + " ");     }   }     // Driver Code   public static void Main()   {     int[] arr = { 12, 5, 3, 9, 21, 36, 17 };     int K = 2;       updateArray(arr, K);   } }   // This code is contributed by ukasp.

## Javascript



Output

5 12 21 36 36 21 36

Time Complexity: O(NlogN)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up
Related Articles