Length of Longest Subarray with same elements in atmost K increments

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

Examples:

Input: arr[] = {2, 0, 4, 6, 7}, K = 6
Output: 3
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: 4
The longest subarray is {12, 10, 16, 20} which can be made as {20, 20, 20, 20} with total increments = 22 ( ≤ K )

Approach:

Below is the implementation of the above approach.

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the length of
// Longest Subarray with same elements
// in atmost K increments
  
#include <bits/stdc++.h>
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[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 code
int main()
{
    int arr[] = { 2, 0, 4, 6, 7 }, K = 6;
    int N = sizeof(arr) / sizeof(arr[0]);
  
    cout << longestSubArray(arr, N, K);
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
chevron_right

Output:
3

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





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, princiraj1992

Article Tags :