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: 4
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++ 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 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 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# 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 |
<script> // Javascript program implementation // of the approach // Function to print 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 pointers
let left = ind - 1, right = ind;
let 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 [ 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 point of the list
start = 0;
// Ending point of the list
let end = length - 1;
while (start <= end)
{
// Finding the middle point 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> |
-1
Time Complexity: O(N * log N)
Auxiliary Space: O(1)