给定具有N个整数和整数K的数组arr [] ,任务是从给定数组中选择K个元素,以使所有值的总和为正,而K个整数中的最大值最小。
例子:
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.
方法:想法是使用两指针技术。步骤如下:
- 对给定的数组进行排序。
- 使用C++中的lower_bound()从上面的数组(例如,在索引idx处)中选择最小的非负值。
- 如果给定数组中不存在正值,则总和始终为负,并且K元素均不满足给定条件。
- 如果存在正整数,则有可能选择总和为正的K个元素。
- 通过使用两个指针技术,我们可以找到K个整数,它们的和为正,如下所示:
- 将左右两个指针分别初始化为(ind – 1)和ind 。
- 如果当前总和+ arr [left]大于0 ,则在左索引处添加元素(为负),以最大程度地减小K个所选元素中的最大值并减小左元素。
- 否则在索引右边添加一个元素,并更新最大值和增量右边。
- 对于上述每个步骤,请递减K。
- 重复上述操作,直到K变为零,左小于零或右到达数组的末尾。
- 如果以上任何一种情况下K都为零,则打印存储的最大值。
- 否则打印“ -1” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to print the maximum from K
// selected elements of the array
pair
kthsmallestelement(vector 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 arr = { -8, -5, -2, -4, -1 };
int n = arr.size();
int k = 2;
// Function Call
pair 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
输出:
-1
时间复杂度: O(N * log N)
辅助空间: O(1)