You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求解HackerRank两栈游戏问题:贪心实现无法通过测试用例求助

两栈游戏问题:贪心解法错误排查

问题描述

给定两个整数栈和一个maxSum值,要求找出从两个栈顶移除元素的最大数量,使得移除元素的总和不超过maxSum。

示例

stack 1: 4 2 4 6 1
stack 2: 2 1 8 5
maxSum=10
输出=4(可移除4、2、2、1,总和4+2+2+1=9≤10)

我的解法问题

我采用贪心思路:每次选择两个栈顶中较小的元素加入总和,直到总和超过maxSum。但代码无法通过多个测试用例,作为DSA新手,恳请帮忙排查问题。

我的代码

int twoStacks(int maxSum, vector<int> a, vector<int> b) {
    int count=0;
    int sum=0;
    int i=0;
    int j=0;
    while(sum<=maxSum){
        if(i<a.size() && j<b.size() && sum+min(a[i],b[j])<=maxSum){
            sum+=min(a[i],b[j]);
            count++;
            if(min(a[i],b[j])==a[i]){
                i++;
            }
            else{
                j++;
            }
        }
        else if(i>=a.size() && j<b.size() && sum+b[j]<=maxSum){
            sum+=b[j];
            count++;
            j++;
        }
        else if(i<a.size() && j>=b.size() && sum+a[i]<=maxSum){
            sum+=a[i];
            count++;
            i++;
        }
        else{
            break;
        }
    }
    return count;
}

问题根源:贪心策略的局限性

你的贪心思路(每次选当前栈顶较小的元素)无法覆盖所有最优情况,因为局部最优不代表全局最优。举个反例:

  • stack1: [3, 0, 0, 0]
  • stack2: [2, 2]
  • maxSum=4

按你的贪心逻辑,会先选stack2的2(sum=2,count=1),再选stack2的2(sum=4,count=2),但最优解是选stack1的3+0+0(sum=3≤4,count=3),数量更多。这说明只看当前最小元素,会错过后续能拿更多元素的组合。

正确解法:前缀和+双指针

正确的思路是先累加其中一个栈的元素到最大可能数量,再逐步替换为另一个栈的元素,记录过程中的最大总数量。这种方法能覆盖所有可能的元素组合,时间复杂度为O(n+m),效率很高。

代码实现

int twoStacks(int maxSum, vector<int> a, vector<int> b) {
    int n = a.size(), m = b.size();
    int sum = 0, count = 0;
    
    // 先累加栈a的元素,直到总和超过maxSum
    while (count < n && sum + a[count] <= maxSum) {
        sum += a[count];
        count++;
    }
    int max_count = count; // 记录当前最大数量
    
    // 逐步减少栈a的元素,同时加入栈b的元素,更新最大数量
    int j = 0;
    while (count > 0 && j < m) {
        sum -= a[--count]; // 移除一个栈a的元素
        // 尽可能加入栈b的元素
        while (j < m && sum + b[j] <= maxSum) {
            sum += b[j];
            j++;
        }
        max_count = max(max_count, count + j); // 更新最大数量
    }
    
    return max_count;
}

解法说明

  1. 前缀累加:先把栈a的元素逐个加入总和,直到无法再加入,此时得到栈a能单独拿的最大数量。
  2. 双指针替换:从栈a的最大数量开始,逐个移除元素,同时尝试加入栈b的元素,每次计算当前总数量(栈a剩余数量+栈b已加入数量),记录最大值。
  3. 覆盖所有组合:这种方式遍历了所有“k个栈a元素+l个栈b元素”的合法组合,确保找到数量最多的那一组。

内容的提问来源于stack exchange,提问作者Gourav kr Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:15:57