 Open in App
Not now

# 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 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)

Related Topic: Segment Tree

My Personal Notes arrow_drop_up