Select K elements from an array whose maximum value is minimized

Given an array arr[] having N integers and an integer K, the task is to select K elements from the given array such that sum of all the value is positive and 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 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 possibility of selecting K elements whose sum is positive.
  • By using two pointers technique we can find K integers whose sum is positive as: 
    • Initialise 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 minimized the maximum value among K selected elements and decrement the left.
    • Else add element at index right and update the maximum value and increment right.
    • Decrement K for each of the above step.
    • 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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.




My Personal Notes arrow_drop_up

Recommended Posts:


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.