Skip to content
Related Articles

Related Articles

Improve Article
Select K elements from an array whose maximum value is minimized
  • Last Updated : 11 May, 2021

Given an array arr[] having N integers and an integer K, the task is to select K elements from the given array such that the sum of all the values is positive and the maximum value among K integers is minimum.

Examples: 

Input: arr[] = {10, -8, 5, -5, -2, 4, -1, 0, 11}, k = 4 
Output:
Explanation: 
Possible array is {0, 4, -1, -2} the maximum element is 4 which is the minimum possible.
Input: arr[] = {-8, -5, -2, -4, -1}, k = 2 
Output: -1 
Explanation: 
Selecting K elements is not possible.

Approach: The idea is to use the Two Pointer Technique. Below are the steps:

  • Sort the given array.
  • Select the least non-negative value from the above array(say at index idx) using lower_bound() in C++.
  • If a positive value doesn’t exist in a given array, then the sum is always negative and none of the K element satisfies the given condition.
  • If there exist positive integers then there can be a possibility of selecting K elements whose sum is positive.
  • By using two pointers technique we can find K integers whose sum is positive as: 
    • Initialize two pointers left and right as (ind – 1) and ind respectively.
    • Add the element at index left(which is negative) if current sum + arr[left] is greater than 0 to minimize the maximum value among K selected elements and decrement the left.
    • Else add an element at index right and update the maximum value and increment right.
    • Decrement K for each of the above steps.
    • Repeat the above till K becomes zero, left is less than zero, or right reaches the end of the array.
  • If K becomes zero in any of the above then print the maximum value stored.
  • Else print “-1”.

Below is the implementation of the above approach:



C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to  print the maximum from K
// selected elements of the array
pair<int, bool>
kthsmallestelement(vector<int> a,
                   int n, int k)
{
    // Sort the array
    sort(a.begin(), a.end());
 
    // Apply Binary search for
    // first positive element
    int ind = lower_bound(a.begin(),
                          a.end(), 0)
              - a.begin();
 
  // Check if no element is positive
    if (ind == n - 1 && a[n - 1] < 0)
        return make_pair(INT_MAX, false);
 
    // Initialize pointers
    int left = ind - 1, right = ind;
    int sum = 0;
 
    // Iterate to select exactly K elements
    while (k--) {
 
        // Check if left pointer
        // is greater than 0
        if (left >= 0 && sum + a[left] > 0) {
 
            // Update sum
            sum = sum + a[left];
            // Decrement left
            left--;
        }
 
        else if (right < n) {
 
            // Update sum
            sum = sum + a[right];
 
            // Increment right
            right++;
        }
 
        else
            return make_pair(INT_MAX, false);
    }
 
    // Return the answer
    return make_pair(a[right - 1], true);
}
 
// Driver Code
int main()
{
    // Given array arr[]
    vector<int> arr = { -8, -5, -2, -4, -1 };
 
    int n = arr.size();
    int k = 2;
 
    // Function Call
    pair<int, bool> ans
        = kthsmallestelement(arr, n, k);
 
    if (ans.second == false)
        cout << "-1" << endl;
 
    else
        cout << ans.first << endl;
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to print the maximum from K
// selected elements of the array
static int[] kthsmallestelement(int[] a, int n,
                                int k)
{
     
    // Sort the array
    Arrays.sort(a);
 
    // Apply Binary search for
    // first positive element
    int ind = lowerBound(a, 0, a.length, 0);
 
    // Check if no element is positive
    if (ind == n - 1 && a[n - 1] < 0)
        return new int[] { Integer.MAX_VALUE, 0 };
 
    // Initialize pointers
    int left = ind - 1, right = ind;
    int sum = 0;
 
    // Iterate to select exactly K elements
    while (k-- > 0)
    {
 
        // Check if left pointer
        // is greater than 0
        if (left >= 0 && sum + a[left] > 0)
        {
 
            // Update sum
            sum = sum + a[left];
            // Decrement left
            left--;
        }
 
        else if (right < n)
        {
 
            // Update sum
            sum = sum + a[right];
 
            // Increment right
            right++;
        }
        else
            return new int[] { Integer.MAX_VALUE, 0 };
    }
 
    // Return the answer
    return new int[] { a[right - 1], 1 };
}
 
static int lowerBound(int[] numbers, int start,
                      int length, int searchnum)
{
     
    // If the number is not in the
    // list it will return -1
    int answer = -1;
 
    // Starting point of the list
    start = 0;
 
    // Ending point of the list
    int end = length - 1;
 
    while (start <= end)
    {
 
        // Finding the middle point of the list
        int middle = (start + end) / 2;
 
        if (numbers[middle] == searchnum)
        {
            answer = middle;
            end = middle - 1;
        } else if (numbers[middle] > searchnum)
            end = middle - 1;
        else
            start = middle + 1;
    }
    if (answer == -1)
        answer = length;
 
    return answer;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array arr[]
    int[] arr = { -8, -5, -2, -4, -1 };
 
    int n = arr.length;
    int k = 2;
 
    // Function call
    int[] ans = kthsmallestelement(arr, n, k);
 
    if (ans[1] == 0)
        System.out.print("-1" + "\n");
    else
        System.out.print(ans[0] + "\n");
}
}
 
// This code is contributed by amal kumar choubey

Python3




# Python3 program for the above approach
import sys
 
# Function to find lower_bound
def LowerBound(numbers, length, searchnum):
     
    # If the number is not in the
    # list it will return -1
    answer = -1
     
    # Starting point of the list
    start = 0
     
    # Ending point of the list
    end = length - 1
     
    while start <= end:
         
        # Finding the middle point of the list
        middle = (start + end) // 2
         
        if numbers[middle] == searchnum:
            answer = middle
            end = middle - 1
        elif numbers[middle] > searchnum:
            end = middle - 1
        else:
            start = middle + 1
     
    if(answer == -1):
        answer = length
 
    return answer
 
# Function to print the maximum from K
# selected elements of the array
def kthsmallestelement(a, n, k):
     
    # Sort the array
    a.sort()
 
    # Apply Binary search for
    # first positive element
    ind = LowerBound(a, len(a), 0)
 
    # Check if no element is positive
    if (ind == n - 1 and a[n - 1] < 0):
        return make_pair(INT_MAX, False)
 
    # Initialize pointers
    left = ind - 1
    right = ind
    sum = 0
 
    # Iterate to select exactly K elements
    while (k > 0):
        k -= 1
         
        # Check if left pointer
        # is greater than 0
        if (left >= 0 and sum + a[left] > 0):
             
            # Update sum
            sum = sum + a[left]
             
            # Decrement left
            left -= 1
             
        elif (right < n):
             
            # Update sum
            sum = sum + a[right]
             
            # Increment right
            right += 1
        else:
            return [sys.maxsize, False]
 
    print(sys.maxsize)
     
    # Return the answer
    return [a[right - 1], True]
 
# Driver Code
 
# Given array arr[]
arr = [ -8, -5, -2, -4, -1 ]
 
n = len(arr)
k = 2
 
# Function call
ans = kthsmallestelement(arr, n, k)
 
if (ans[1] == False):
    print(-1)
else:
    print(ans[0])
 
# This code is contributed by Sanjit_Prasad

C#




// C# program for the above approach
using System;
 
class GFG{
 
// Function to print the maximum from K
// selected elements of the array
static int[] kthsmallestelement(int[] a, int n,
                                int k)
{
     
    // Sort the array
    Array.Sort(a);
 
    // Apply Binary search for
    // first positive element
    int ind = lowerBound(a, 0, a.Length, 0);
 
    // Check if no element is positive
    if (ind == n - 1 && a[n - 1] < 0)
        return new int[] { int.MaxValue, 0 };
 
    // Initialize pointers
    int left = ind - 1, right = ind;
    int sum = 0;
 
    // Iterate to select exactly K elements
    while (k-- > 0)
    {
 
        // Check if left pointer
        // is greater than 0
        if (left >= 0 && sum + a[left] > 0)
        {
 
            // Update sum
            sum = sum + a[left];
             
            // Decrement left
            left--;
        }
 
        else if (right < n)
        {
 
            // Update sum
            sum = sum + a[right];
 
            // Increment right
            right++;
        }
        else
            return new int[] { int.MaxValue, 0 };
    }
 
    // Return the answer
    return new int[] { a[right - 1], 1 };
}
 
static int lowerBound(int[] numbers, int start,
                      int length, int searchnum)
{
     
    // If the number is not in the
    // list it will return -1
    int answer = -1;
 
    // Starting point of the list
    start = 0;
 
    // Ending point of the list
    int end = length - 1;
 
    while (start <= end)
    {
 
        // Finding the middle point of the list
        int middle = (start + end) / 2;
 
        if (numbers[middle] == searchnum)
        {
            answer = middle;
            end = middle - 1;
        } else if (numbers[middle] > searchnum)
            end = middle - 1;
        else
            start = middle + 1;
    }
    if (answer == -1)
        answer = length;
 
    return answer;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given array []arr
    int[] arr = { -8, -5, -2, -4, -1 };
 
    int n = arr.Length;
    int k = 2;
 
    // Function call
    int[] ans = kthsmallestelement(arr, n, k);
 
    if (ans[1] == 0)
        Console.Write("-1" + "\n");
    else
        Console.Write(ans[0] + "\n");
}
}
 
// This code is contributed by Amit Katiyar

Javascript




<script>
 
// Javascript program implementation
// of the approach
 
// Function to prlet the maximum from K
// selected elements of the array
function kthsmallestelement(a, n, k)
{
       
    // Sort the array
    a.sort();
   
    // Apply Binary search for
    // first positive element
    let ind = lowerBound(a, 0, a.length, 0);
   
    // Check if no element is positive
    if (ind == n - 1 && a[n - 1] < 0)
        return [ Number.MAX_VALUE, 0 ];
   
    // Initialize poleters
    let left = ind - 1, right = ind;
    let sum = 0;
   
    // Iterate to select exactly K elements
    while (k-- > 0)
    {
   
        // Check if left poleter
        // is greater than 0
        if (left >= 0 && sum + a[left] > 0)
        {
   
            // Update sum
            sum = sum + a[left];
            // Decrement left
            left--;
        }
   
        else if (right < n)
        {
   
            // Update sum
            sum = sum + a[right];
   
            // Increment right
            right++;
        }
        else
            return [ Number.MAX_VALUE, 0 ];
    }
   
    // Return the answer
    return [ a[right - 1], 1 ];
}
   
function lowerBound( numbers, start,
                      length, searchnum)
{
       
    // If the number is not in the
    // list it will return -1
    let answer = -1;
   
    // Starting polet of the list
    start = 0;
   
    // Ending polet of the list
    let end = length - 1;
   
    while (start <= end)
    {
   
        // Finding the middle polet of the list
        let middle = (start + end) / 2;
   
        if (numbers[middle] == searchnum)
        {
            answer = middle;
            end = middle - 1;
        } else if (numbers[middle] > searchnum)
            end = middle - 1;
        else
            start = middle + 1;
    }
    if (answer == -1)
        answer = length;
   
    return answer;
}
 
// Driver Code
     
    // Given array arr[]
    let arr = [ -8, -5, -2, -4, -1 ];
   
    let n = arr.length;
    let k = 2;
   
    // Function call
    let ans = kthsmallestelement(arr, n, k);
   
    if (ans[1] == 0)
        document.write("-1" + "\n");
    else
        document.write(ans[0] + "\n");
          
</script>
Output: 
-1

 

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

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 industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :