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

• Difficulty Level : Hard
• Last Updated : 10 Jun, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 tree``int` `segment_tree[4 * 1000000];` `// Function that builds the segment``// tree to return the max element``// in a range``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]``            ``= 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``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` `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 = A;``    ``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 code``int` `main()``{``    ``int` `arr[] = { 2, 0, 4, 6, 7 }, K = 6;``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``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 = A;``        ``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)

My Personal Notes arrow_drop_up