📌  相关文章
📜  从给定的两个堆栈中选择的最大整数个数,总和最多为 K

📅  最后修改于: 2022-05-13 01:56:09.126000             🧑  作者: Mango

从给定的两个堆栈中选择的最大整数个数,总和最多为 K

给定两个大小分别为NM的栈stack1[]stack2[]以及一个整数K ,任务是计算两个栈中总和小于或等于K的最大整数个数。

例子:

方法:这个问题不能使用贪心方法解决,因为在每一步都将选择具有最小值的数字,但第一个示例会因此失败。这个问题可以使用前缀求和二分查找来解决。计算两个堆栈的前缀总和,现在迭代第一个堆栈的每个可能值并获取目标,即(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)