通过率 54% · 提交 768 · 通过 417
小慕正在处理一个数据压缩项目,他使用一个空栈来依次压入正整数。每当压入一个整数时,需要执行以下规则(设:,其中 n1 为最新压入的整数): 1. 如果 n1 = n2,则 n1、n2 全部,压入新数据 m(m = 2 * n1)。 2. 如果 (y 的范围为 [3, x]),则 n1、n2、...、ny 全部出栈,压入新数据 m(m = 2 * n1)。 3. 如果上述规则都不满足,则不做操作。 例如:小慕依次向栈压入 6、1、2、3。当压入 2 时,栈顶至栈底依次为 [2, 1, 6];当压入 3 时,3 = 2 + 1,3、2、1 全部出栈,重新入栈整数 6,此时栈顶至栈底依次为 [6, 6];6 = 6,两个 6 全部出栈,压入 12,最终栈中只剩一个元素 12。 小慕向栈中输入一串数字,请输出应用此规则后栈中最终存留的数字。
这类题属于华为 OD 机考真题方向中「200分 / 2024E」方向的高频题型,通常考察对「200分 / 2024E」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
使用单个空格隔开的正整数的字符串,如 "5 6 7 8",左边的数字先入栈。
正整数大小为 [1, 2^31−1]。
正整数个数为 [1,1000]。
最终栈中存留的元素值,元素值使用单个空格隔开,如 "8 7 6 5",从左至右依次为栈顶至栈底的数字。
示例 1
输入示例
10 20 50 80 1 1
输出示例
2 160
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
注意,本题最初见于 华为2023年校招暑期实习 的题目,在 OJ 上直接搜索 空栈压数 即可搜索得到题目。
由于本题的数据量较小,最多仅为 1000。可以直接使用 栈 的数据结构,对题目进行 模拟 即可。
题目所给定的两种出栈情况,实际上可以归纳为 同一种表述。 当某一个元素即将入栈时,如果发现栈顶的若干连续元素的和恰好等于该元素,则令栈中的这些若干连续元素出栈,换成将 两倍 的该元素入栈。
所以我们只需要在每一个元素入栈之前,都进行上述过程的判断即可。
我们可以构建这样的一个函数:
在这个函数中,我们构建了参数 top_sum 表示栈顶元素和的情况,用索引 idx 从后往前逐个遍历。 一旦发现 top_sum >= num 的时候,则退出 while 循环。
退出 while 的时候,我们还需进一步做出判断,若:
num 入栈特别需要注意的地方在于,如果此时我们是要把两倍的 num 入栈,那么这个时候又是一个新的数 2 * num 入栈,我们需要 重复判断 是否存在若干连续栈顶元素的和为当前入栈的 2 * num 这个过程。
比如题目描述中所给的例子,入栈顺序是 6 1 2 3 时,当 3 准备入栈时,发现栈顶元素 2 1 的和为 3,此时会弹出 2 1,将 3 * 2 = 6 作为即将入栈的元素。而当 6 准备入栈时,又发现了此时栈顶元素 6 和准备入栈的 6 相等,因此将栈顶元素 6 弹出,令 6 * 2 = 12 入栈。
由于无法判断上述重复判断入栈的过程需要几次,因此我们在函数外部设置了一个 `while` 循环。 使用一个 bool 类型标志 flag_continue_loop 来表示,在 check_stack_top(stack, num) 函数中我们是否弹出了若干连续栈顶元素并且令 2 * num 准备入栈。
相对应的,check_stack_top(stack, num) 函数也需要加上关于 flag_continue_loop 的修改。 我们可以把 flag_continue_loop 作为一个 全局变量 来使用,当:
top_sum == num 的时候,修改 flag_continue_loop = Truetop_sum != num 的时候,修改 flag_continue_loop = False最终 check_stack_top(stack, num) 呈现的代码为:
将上述所有代码组织到一起,加上输入和输出内容,本题就完成了。
复杂度分析
设 n 为输入数字的个数。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有