从给定的两个堆栈中选择的最大整数个数,总和最多为 K
给定两个大小分别为N和M的栈stack1[]和stack2[]以及一个整数K ,任务是计算两个栈中总和小于或等于K的最大整数个数。
例子:
Input: stack1[ ] = { 60, 90, 120 }
stack2[ ] = { 100, 10, 10, 250 }, K = 130
Output: 3
Explanation: Take 3 numbers from stack1 which are 100 and 10 and 10.
Total sum 100 + 10 + 10 = 120
Input: stack1[ ] = { 60, 90, 120 }
stack2[ ] = { 80, 150, 80, 150 }, K = 740
Output: 7
Explanation: Select all the numbers because the value K is enough.
方法:这个问题不能使用贪心方法解决,因为在每一步都将选择具有最小值的数字,但第一个示例会因此失败。这个问题可以使用前缀求和和二分查找来解决。计算两个堆栈的前缀总和,现在迭代第一个堆栈的每个可能值并获取目标,即(K – stack1[i])并在第二个堆栈上应用二进制搜索以获取stack2[]的下限。
请按照以下步骤操作:
- 取两个新堆栈,它们是sumA[]和 sumB[ ] 。
- 计算堆栈stack1[]和stack2[]的前缀。
- 迭代第一个堆栈。
- 现在,获取remValueOfK变量并存储(K – stack1[i]) 。
- 如果小于 0 则继续循环。
- 否则取第二个堆栈的下限。
- 如果下限大于第二个堆栈的大小或下限的值大于remValueOfK的值,则只需减少下限变量的值。
- 存储所选元素的最大数量并将其作为最终答案返回。
下面是上述方法的实现。
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to find the
// maximum number of elements
int maxNumbers(int stack1[], int N, int stack2[],
int M, int K)
{
// Take prefix of both the stack
vector sumA(N + 1, 0);
vector sumB(M + 1, 0);
for (int i = 0; i < N; i++)
sumA[i + 1] = sumA[i] + stack1[i];
for (int i = 0; i < M; i++)
sumB[i + 1] = sumB[i] + stack2[i];
// Calculate maxNumbers
int MaxNumbers = 0;
for (int i = 0; i <= N; i++) {
// Calculate remaining value of K
// after selecting numbers
// from 1st stack
int remValueOfK = K - sumA[i];
// If rem value of K is less than 0
// continue the loop
if (remValueOfK < 0)
continue;
// Calculate lower bound
int lowerBound
= lower_bound(sumB.begin(),
sumB.end(),
remValueOfK)
- sumB.begin();
// If size of lower bound is greater
// than self stack size or
// value of lower bound element
// decrement lowerBound
if (lowerBound > M
or sumB[lowerBound] > remValueOfK) {
lowerBound--;
}
// Store max possible numbers
int books = i + lowerBound;
MaxNumbers = max(MaxNumbers, books);
}
return MaxNumbers;
}
// Driver code
int main()
{
int stack1[] = { 60, 90, 120 };
int stack2[] = { 100, 10, 10, 200 };
int K = 130;
int N = 3;
int M = 4;
int ans
= maxNumbers(stack1, N, stack2, M, K);
cout << ans;
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG
{
static int lower_bound(int []a, int val) {
int lo = 0, hi = a.length - 1;
while (lo < hi) {
int mid = (int)Math.floor(lo + (double)(hi - lo) / 2);
if (a[mid] < val)
lo = mid + 1;
else
hi = mid;
}
return lo;
}
// Function to find the
// maximum number of elements
static int maxNumbers(int []stack1, int N, int []stack2,
int M, int K) {
// Take prefix of both the stack
int []sumA = new int[N + 1];
for(int i = 0; i < N + 1; i++) {
sumA[i] = 0;
}
int []sumB = new int[M + 1];
for(int i = 0; i < M + 1; i++) {
sumB[i] = 0;
}
for (int i = 0; i < N; i++)
sumA[i + 1] = sumA[i] + stack1[i];
for (int i = 0; i < M; i++)
sumB[i + 1] = sumB[i] + stack2[i];
// Calculate maxNumbers
int MaxNumbers = 0;
for (int i = 0; i <= N; i++) {
// Calculate remaining value of K
// after selecting numbers
// from 1st stack
int remValueOfK = K - sumA[i];
// If rem value of K is less than 0
// continue the loop
if (remValueOfK < 0)
continue;
// Calculate lower bound
int lowerBound
= lower_bound(sumB,
remValueOfK);
// If size of lower bound is greater
// than self stack size or
// value of lower bound element
// decrement lowerBound
if (lowerBound > M
|| sumB[lowerBound] > remValueOfK) {
lowerBound--;
}
// Store max possible numbers
int books = i + lowerBound;
MaxNumbers = Math.max(MaxNumbers, books);
}
return MaxNumbers;
}
// Driver Code
public static void main(String args[])
{
int []stack1 = {60, 90, 120};
int []stack2 = {100, 10, 10, 200};
int K = 130;
int N = 3;
int M = 4;
int ans = maxNumbers(stack1, N, stack2, M, K);
System.out.println(ans);
}
}
// This code is contributed by sanjoy_62.
Python3
# Python code for the above approach
def lower_bound(a, val):
lo = 0
hi = len(a) - 1;
while (lo < hi):
mid = (lo + (hi - lo) // 2);
if (a[mid] < val):
lo = mid + 1;
else:
hi = mid;
return lo;
# Function to find the
# maximum number of elements
def maxNumbers(stack1, N, stack2, M, K):
# Take prefix of both the stack
sumA = [0] * (N + 1)
sumB = [0] * (M + 1)
for i in range(N):
sumA[i + 1] = sumA[i] + stack1[i];
for i in range(M):
sumB[i + 1] = sumB[i] + stack2[i];
# Calculate maxNumbers
MaxNumbers = 0;
for i in range(N + 1):
# Calculate remaining value of K
# after selecting numbers
# from 1st stack
remValueOfK = K - sumA[i];
# If rem value of K is less than 0
# continue the loop
if (remValueOfK < 0):
continue;
# Calculate lower bound
lowerBound = lower_bound(sumB, remValueOfK);
# If size of lower bound is greater
# than self stack size or
# value of lower bound element
# decrement lowerBound
if (lowerBound > M or sumB[lowerBound] > remValueOfK):
lowerBound -= 1
# Store max possible numbers
books = i + lowerBound;
MaxNumbers = max(MaxNumbers, books);
return MaxNumbers;
# Driver code
stack1 = [60, 90, 120];
stack2 = [100, 10, 10, 200];
K = 130;
N = 3;
M = 4;
ans = maxNumbers(stack1, N, stack2, M, K);
print(ans)
# This code is contributed by gfgking
C#
// C# code for the above approach
using System;
class GFG
{
static int lower_bound(int []a, int val) {
int lo = 0, hi = a.Length - 1;
while (lo < hi) {
int mid = (int)Math.Floor(lo + (double)(hi - lo) / 2);
if (a[mid] < val)
lo = mid + 1;
else
hi = mid;
}
return lo;
}
// Function to find the
// maximum number of elements
static int maxNumbers(int []stack1, int N, int []stack2,
int M, int K) {
// Take prefix of both the stack
int []sumA = new int[N + 1];
for(int i = 0; i < N + 1; i++) {
sumA[i] = 0;
}
int []sumB = new int[M + 1];
for(int i = 0; i < M + 1; i++) {
sumB[i] = 0;
}
for (int i = 0; i < N; i++)
sumA[i + 1] = sumA[i] + stack1[i];
for (int i = 0; i < M; i++)
sumB[i + 1] = sumB[i] + stack2[i];
// Calculate maxNumbers
int MaxNumbers = 0;
for (int i = 0; i <= N; i++) {
// Calculate remaining value of K
// after selecting numbers
// from 1st stack
int remValueOfK = K - sumA[i];
// If rem value of K is less than 0
// continue the loop
if (remValueOfK < 0)
continue;
// Calculate lower bound
int lowerBound
= lower_bound(sumB,
remValueOfK);
// If size of lower bound is greater
// than self stack size or
// value of lower bound element
// decrement lowerBound
if (lowerBound > M
|| sumB[lowerBound] > remValueOfK) {
lowerBound--;
}
// Store max possible numbers
int books = i + lowerBound;
MaxNumbers = Math.Max(MaxNumbers, books);
}
return MaxNumbers;
}
// Driver code
public static void Main() {
int []stack1 = {60, 90, 120};
int []stack2 = {100, 10, 10, 200};
int K = 130;
int N = 3;
int M = 4;
int ans = maxNumbers(stack1, N, stack2, M, K);
Console.Write(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
3
时间复杂度: O(N * logN)
辅助空间: O(N)