# Length of Longest Subarray with same elements in atmost K increments

• Difficulty Level : Hard
• Last Updated : 11 Jul, 2022

Given an integer array arr and a number K, the task is to find the length of the longest subarray such that all the elements in this subarray can be made the same in atmost K increments.

Examples:

Input: arr[] = {2, 0, 4, 6, 7}, K = 6
Output:
The longest subarray is {2, 0, 4} which can be made as {4, 4, 4} with total increments = 6 ( â‰¤ K )

Input: arr[] = {12, 10, 16, 20, 7, 11}, K = 25
Output:
The longest subarray is {12, 10, 16, 20} which can be made as {20, 20, 20, 20} with total increments = 22 ( â‰¤ K )

Approach:

• A variable i will be used to store the start point of the required longest subarray, and a variable j for the endpoint. Hence, the range will be [i, j]
• Initially, assume the valid range to be [0, N).
• The actual range [i, j] will be computed using binary search. For each search performed:
• A Segment Tree can be used to find the maximum element in the range [i, j]
• Make all the elements in the range [i, j] equal to the found max element.
• Then, use a prefix sum array to get the sum of elements in the range [i, j].
• Then, the number of increments required in this range can be calculated as:
Total number of increments
= (j - i + 1) * (max_value) - Î£(i, j)

where i = index of the starting point of the subarray
j = index of end point of subarray
max_value = maximum value from index i to j
Î£(i, j) = sum of all elements from index i to j
• If the number of increments required is less than or equal to K, it is a valid subarray, else it is invalid.
• For invalid subarray, update the start and end points accordingly for the next Binary Search
• Return the length of the longest such subarray range.

Below is the implementation of the above approach:

## C++

 // C++ program to find the length of// Longest Subarray with same elements// in atmost K increments  #include using namespace std;  // Initialize array for segment treeint segment_tree[4 * 1000000];  // Function that builds the segment// tree to return the max element// in a rangeint build(int* A, int start, int end,          int node){    if (start == end)        // update the value in segment        // tree from given array        segment_tree[node] = A[start];      else {        // find the middle index        int mid = (start + end) / 2;          // If there are more than one        // elements, then recur for left        // and right subtrees and        // store the max of values in this node        segment_tree[node]            = max(                build(A, start, mid, 2 * node + 1),                build(A, mid + 1, end, 2 * node + 2));    }    return segment_tree[node];}  // Function to return the max// element in the given rangeint query(int start, int end, int l, int r,          int node){    // If the range is out of bounds,    // return -1      if (start > r || end < l)        return -1;    if (start >= l && end <= r)        return segment_tree[node];    int mid = (start + end) / 2;      return max(query(start, mid, l,                     r, 2 * node + 1),               query(mid + 1, end, l,                     r, 2 * node + 2));}  // Function that returns length of longest// subarray with same elements in atmost// K increments.int longestSubArray(int* A, int N, int K){      // Initialize the result variable    // Even though the K is 0,    // the required longest subarray,    // in that case, will also be of length 1    int res = 1;      // Initialize the prefix sum array    int preSum[N + 1];      // Build the prefix sum array    preSum[0] = A[0];    for (int i = 0; i < N; i++)        preSum[i + 1] = preSum[i] + A[i];      // Build the segment tree    // for range max query    build(A, 0, N - 1, 0);      // Loop through the array    // with a starting point as i    // for the required subarray till    // the longest subarray is found    for (int i = 0; i < N; i++) {          int start = i, end = N - 1,            mid, max_index = i;          // Performing the binary search        // to find the endpoint        // for the selected range        while (start <= end) {              // Find the mid for binary search            mid = (start + end) / 2;              // Find the max element            // in the range [i, mid]            // using Segment Tree            int max_element                = query(0, N - 1,                        i, mid, 0);              // Total sum of subarray after increments            int expected_sum = (mid - i + 1)                               * max_element;              // Actual sum of elements            // before increments            int actual_sum = preSum[mid + 1]                             - preSum[i];              // Check if such increment is possible            // If true, then current i            // is the actual starting point            // of the required longest subarray            if (expected_sum - actual_sum <= K) {                  // Now for finding the endpoint                // for this range                // Perform the Binary search again                // with the updated start                start = mid + 1;                  // Store max end point for the range                // to give longest subarray                max_index = max(max_index, mid);            }              // If false, it means that            // the selected range is invalid            else {                  // Perform the Binary Search again                // with the updated end                end = mid - 1;            }        }          // Store the length of longest subarray        res = max(res, max_index - i + 1);    }      // Return result    return res;}  // Driver codeint main(){    int arr[] = { 2, 0, 4, 6, 7 }, K = 6;    int N = sizeof(arr) / sizeof(arr[0]);      cout << longestSubArray(arr, N, K);      return 0;}

## Java

 // Java program to find the length of // Longest Subarray with same elements // in atmost K increments class GFG {          // Initialize array for segment tree     static int segment_tree[] = new int[4 * 1000000];           // Function that builds the segment     // tree to return the max element     // in a range     static int build(int A[], int start, int end,                      int node)     {         if (start == end)                       // update the value in segment             // tree from given array             segment_tree[node] = A[start];               else         {                           // find the middle index             int mid = (start + end) / 2;                   // If there are more than one             // elements, then recur for left             // and right subtrees and             // store the max of values in this node             segment_tree[node] = Math.max(                     build(A, start, mid, 2 * node + 1),                     build(A, mid + 1, end, 2 * node + 2));         }         return segment_tree[node];     }           // Function to return the max     // element in the given range     static int query(int start, int end, int l, int r,                      int node)     {         // If the range is out of bounds,         // return -1         if (start > r || end < l)             return -1;         if (start >= l && end <= r)             return segment_tree[node];         int mid = (start + end) / 2;               return Math.max(query(start, mid, l,                         r, 2 * node + 1),                         query(mid + 1, end, l,                         r, 2 * node + 2));     }           // Function that returns length of longest     // subarray with same elements in atmost     // K increments.     static int longestSubArray(int A[], int N, int K)     {               // Initialize the result variable         // Even though the K is 0,         // the required longest subarray,         // in that case, will also be of length 1         int res = 1;               // Initialize the prefix sum array         int preSum[] = new int[N + 1];               // Build the prefix sum array         preSum[0] = A[0];         for (int i = 0; i < N; i++)             preSum[i + 1] = preSum[i] + A[i];               // Build the segment tree         // for range max query         build(A, 0, N - 1, 0);               // Loop through the array         // with a starting point as i         // for the required subarray till         // the longest subarray is found         for (int i = 0; i < N; i++)         {                   int start = i, end = N - 1,                 mid, max_index = i;                   // Performing the binary search             // to find the endpoint             // for the selected range             while (start <= end)             {                       // Find the mid for binary search                 mid = (start + end) / 2;                       // Find the max element                 // in the range [i, mid]                 // using Segment Tree                 int max_element = query(0, N - 1,                                         i, mid, 0);                       // Total sum of subarray after increments                 int expected_sum = (mid - i + 1)                                 * max_element;                       // Actual sum of elements                 // before increments                 int actual_sum = preSum[mid + 1]                                 - preSum[i];                       // Check if such increment is possible                 // If true, then current i                 // is the actual starting point                 // of the required longest subarray                 if (expected_sum - actual_sum <= K)                {                           // Now for finding the endpoint                     // for this range                     // Perform the Binary search again                     // with the updated start                     start = mid + 1;                           // Store max end point for the range                     // to give longest subarray                     max_index = Math.max(max_index, mid);                 }                       // If false, it means that                 // the selected range is invalid                 else                 {                           // Perform the Binary Search again                     // with the updated end                     end = mid - 1;                 }             }                   // Store the length of longest subarray             res = Math.max(res, max_index - i + 1);         }               // Return result         return res;     }           // Driver code     public static void main (String[] args)     {         int arr[] = { 2, 0, 4, 6, 7 }, K = 6;         int N = arr.length;               System.out.println(longestSubArray(arr, N, K));     } }  // This code is contributed by AnkitRai01

## Python3

 # Python3 program to find the length of # Longest Subarray with same elements # in atmost K increments   # Initialize array for segment tree segment_tree = [0]*(4 * 1000000);   # Function that builds the segment # tree to return the max element # in a range def build(A, start, end, node) :       if (start == end) :                  # update the value in segment         # tree from given array         segment_tree[node] = A[start];       else :                  # find the middle index         mid = (start + end) // 2;           # If there are more than one         # elements, then recur for left         # and right subtrees and         # store the max of values in this node         segment_tree[node] = max(                 build(A, start, mid, 2 * node + 1),                 build(A, mid + 1, end, 2 * node + 2));       return segment_tree[node];   # Function to return the max # element in the given range def query(start, end, l, r, node) :      # If the range is out of bounds,     # return -1     if (start > r or end < l) :        return -1;               if (start >= l and end <= r) :        return segment_tree[node];              mid = (start + end) // 2;       return max(query(start, mid, l,                     r, 2 * node + 1),             query(mid + 1, end, l,                     r, 2 * node + 2));   # Function that returns length of longest # subarray with same elements in atmost # K increments. def longestSubArray(A, N, K) :       # Initialize the result variable     # Even though the K is 0,     # the required longest subarray,     # in that case, will also be of length 1     res = 1;       # Initialize the prefix sum array     preSum = [0] * (N + 1);       # Build the prefix sum array     preSum[0] = A[0];     for i in range(N) :        preSum[i + 1] = preSum[i] + A[i];       # Build the segment tree     # for range max query     build(A, 0, N - 1, 0);       # Loop through the array     # with a starting point as i     # for the required subarray till     # the longest subarray is found     for i in range(N) :          start = i;        end = N - 1;        max_index = i;           # Performing the binary search         # to find the endpoint         # for the selected range         while (start <= end) :              # Find the mid for binary search             mid = (start + end) // 2;               # Find the max element             # in the range [i, mid]             # using Segment Tree             max_element = query(0, N - 1, i, mid, 0);               # Total sum of subarray after increments             expected_sum = (mid - i + 1) * max_element;               # Actual sum of elements             # before increments             actual_sum = preSum[mid + 1] - preSum[i];               # Check if such increment is possible             # If true, then current i             # is the actual starting point             # of the required longest subarray             if (expected_sum - actual_sum <= K) :                   # Now for finding the endpoint                 # for this range                 # Perform the Binary search again                 # with the updated start                 start = mid + 1;                   # Store max end point for the range                 # to give longest subarray                 max_index = max(max_index, mid);               # If false, it means that             # the selected range is invalid             else :                  # Perform the Binary Search again                 # with the updated end                 end = mid - 1;           # Store the length of longest subarray         res = max(res, max_index - i + 1);       # Return result     return res;   # Driver code if __name__ == "__main__" :       arr = [ 2, 0, 4, 6, 7 ]; K = 6;     N = len(arr);       print(longestSubArray(arr, N, K));   # This code is contributed by AnkitRai01

## C#

 // C# program to find the length of // longest Subarray with same elements // in atmost K increments using System;  class GFG {          // Initialize array for segment tree     static int []segment_tree = new int[4 * 1000000];           // Function that builds the segment     // tree to return the max element     // in a range     static int build(int []A, int start, int end,                     int node)     {         if (start == end)                       // update the value in segment             // tree from given array             segment_tree[node] = A[start];               else        {                           // find the middle index             int mid = (start + end) / 2;                   // If there are more than one             // elements, then recur for left             // and right subtrees and             // store the max of values in this node             segment_tree[node] = Math.Max(                     build(A, start, mid, 2 * node + 1),                     build(A, mid + 1, end, 2 * node + 2));         }         return segment_tree[node];     }           // Function to return the max     // element in the given range     static int query(int start, int end, int l, int r,                     int node)     {         // If the range is out of bounds,         // return -1         if (start > r || end < l)             return -1;         if (start >= l && end <= r)             return segment_tree[node];         int mid = (start + end) / 2;               return Math.Max(query(start, mid, l,                         r, 2 * node + 1),                         query(mid + 1, end, l,                         r, 2 * node + 2));     }           // Function that returns length of longest     // subarray with same elements in atmost     // K increments.     static int longestSubArray(int []A, int N, int K)     {               // Initialize the result variable         // Even though the K is 0,         // the required longest subarray,         // in that case, will also be of length 1         int res = 1;               // Initialize the prefix sum array         int []preSum = new int[N + 1];               // Build the prefix sum array         preSum[0] = A[0];         for (int i = 0; i < N; i++)             preSum[i + 1] = preSum[i] + A[i];               // Build the segment tree         // for range max query         build(A, 0, N - 1, 0);               // Loop through the array         // with a starting point as i         // for the required subarray till         // the longest subarray is found         for (int i = 0; i < N; i++)         {                   int start = i, end = N - 1,                 mid, max_index = i;                   // Performing the binary search             // to find the endpoint             // for the selected range             while (start <= end)             {                       // Find the mid for binary search                 mid = (start + end) / 2;                       // Find the max element                 // in the range [i, mid]                 // using Segment Tree                 int max_element = query(0, N - 1,                                         i, mid, 0);                       // Total sum of subarray after increments                 int expected_sum = (mid - i + 1)                                 * max_element;                       // Actual sum of elements                 // before increments                 int actual_sum = preSum[mid + 1]                                 - preSum[i];                       // Check if such increment is possible                 // If true, then current i                 // is the actual starting point                 // of the required longest subarray                 if (expected_sum - actual_sum <= K)                {                           // Now for finding the endpoint                     // for this range                     // Perform the Binary search again                     // with the updated start                     start = mid + 1;                           // Store max end point for the range                     // to give longest subarray                     max_index = Math.Max(max_index, mid);                 }                       // If false, it means that                 // the selected range is invalid                 else                {                           // Perform the Binary Search again                     // with the updated end                     end = mid - 1;                 }             }                   // Store the length of longest subarray             res = Math.Max(res, max_index - i + 1);         }               // Return result         return res;     }           // Driver code     public static void Main(String[] args)     {         int []arr = { 2, 0, 4, 6, 7 };        int K = 6;         int N = arr.Length;               Console.WriteLine(longestSubArray(arr, N, K));     } }  // This code is contributed by PrinciRaj1992

## Javascript



Output:

3

Time Complexity: O(N*(log(N))2)

Related Topic: Segment Tree

My Personal Notes arrow_drop_up