堆栈剩余数字问题的多语言实现与算法解析
1. 堆栈剩余数字问题解析最近在技术社区看到一个很有意思的算法题——堆栈中的剩余数字题目要求用Java、JS和Python三种语言分别实现。这个题目看似简单但实际涉及到了堆栈数据结构的核心操作和算法思维特别适合用来检验程序员对不同语言特性的掌握程度。这道题的基本场景是给定一个数字序列将这些数字依次压入堆栈。当堆栈中至少有两个数字时检查最顶部的两个数字。如果这两个数字的和是偶数就将它们从堆栈中弹出。重复这个过程直到不能再操作为止最后返回堆栈中剩余的数字。这个问题在实际开发中有很多变体应用比如游戏中的消除逻辑、编译器中的括号匹配检查甚至是金融交易系统中的订单匹配机制。通过这个练习我们不仅能巩固堆栈数据结构的知识还能对比不同语言在实现同一算法时的差异。2. 算法设计与思路拆解2.1 问题分析与建模首先我们需要明确问题的输入输出输入一个数字数组例如[1, 3, 4, 2, 5, 8]输出经过操作后堆栈中剩余的数字如上述例子应该返回[1, 3, 5]关键操作规则初始化一个空堆栈遍历输入数组将每个数字依次压入堆栈每次压入后检查如果堆栈中至少有两个元素且顶部两个元素之和为偶数如果满足条件弹出这两个元素重复步骤3-4直到不满足条件最终返回堆栈中的剩余元素这个问题的难点在于如何在弹出两个元素后继续检查新的栈顶元素这需要我们在每次操作后都重新检查条件。2.2 算法复杂度分析时间复杂度最坏情况下每个元素都可能被压入和弹出一次所以时间复杂度是O(n)最好情况下所有元素都能被消除时间复杂度也是O(n)空间复杂度我们需要一个堆栈来存储元素最坏情况下所有元素都保留在堆栈中所以空间复杂度是O(n)2.3 边界条件考虑在实现时需要特别注意以下边界情况空输入数组应该返回空堆栈单个元素数组直接返回该元素所有元素都能被消除返回空堆栈连续多个消除操作的情况如[2,4,6,8]应该全部消除大数相加导致的整数溢出问题特别是在JS中3. Java实现详解3.1 基础实现import java.util.Stack; public class StackRemainingNumbers { public static int[] remainingNumbers(int[] nums) { StackInteger stack new Stack(); for (int num : nums) { stack.push(num); while (stack.size() 2) { int top stack.pop(); int second stack.pop(); if ((top second) % 2 0) { continue; // 已经弹出不需要再压入 } else { stack.push(second); stack.push(top); break; } } } int[] result new int[stack.size()]; for (int i result.length - 1; i 0; i--) { result[i] stack.pop(); } return result; } }3.2 Java实现优化上面的基础实现有几个可以优化的点使用Deque代替StackJava的Stack类是基于Vector实现的性能不如ArrayDeque避免频繁的装箱拆箱操作结果数组可以直接按顺序填充不需要反向操作优化后的版本import java.util.ArrayDeque; import java.util.Deque; public class StackRemainingNumbersOptimized { public static int[] remainingNumbers(int[] nums) { DequeInteger stack new ArrayDeque(); for (int num : nums) { stack.push(num); while (stack.size() 2) { int top stack.pop(); int second stack.pop(); if ((top second) % 2 ! 0) { stack.push(second); stack.push(top); break; } } } int[] result new int[stack.size()]; int index stack.size() - 1; while (!stack.isEmpty()) { result[index--] stack.pop(); } return result; } }3.3 Java实现注意事项线程安全如果在多线程环境下使用需要考虑使用线程安全的堆栈实现内存使用对于大数组递归实现可能导致栈溢出应该使用迭代方法API选择Java提供了多种集合类根据场景选择最合适的性能测试对于高频调用的场景应该进行性能测试和优化4. JavaScript实现详解4.1 基础实现function remainingNumbers(nums) { const stack []; for (const num of nums) { stack.push(num); while (stack.length 2) { const top stack.pop(); const second stack.pop(); if ((top second) % 2 0) { continue; } else { stack.push(second); stack.push(top); break; } } } return stack; }4.2 JS实现优化JavaScript中的数组已经提供了很好的堆栈操作支持但我们可以做以下优化使用更简洁的条件判断避免不必要的变量声明考虑使用类型数组(如Int32Array)处理大数集优化后的版本function remainingNumbersOptimized(nums) { const stack []; nums.forEach(num { stack.push(num); let top, second; while (stack.length 2 ((top stack.pop(), second stack.pop(), (top second) % 2 0))) { // 已经弹出继续检查 } if (top ! undefined (top second) % 2 ! 0) { stack.push(second, top); } }); return stack; }4.3 JS实现注意事项数字精度JS中所有数字都是64位浮点数大整数相加可能导致精度丢失数组性能JS数组是动态类型的对于纯数字操作可能不是最高效的严格模式建议使用严格模式(use strict)避免意外错误ES6特性可以使用const/let代替varfor...of代替for循环等新特性5. Python实现详解5.1 基础实现def remaining_numbers(nums): stack [] for num in nums: stack.append(num) while len(stack) 2: top stack.pop() second stack.pop() if (top second) % 2 0: continue else: stack.append(second) stack.append(top) break return stack5.2 Python实现优化Python的实现可以有以下优化点使用列表的切片操作简化代码使用更Pythonic的写法添加类型注解提高代码可读性优化后的版本from typing import List def remaining_numbers_optimized(nums: List[int]) - List[int]: stack: List[int] [] for num in nums: stack.append(num) while len(stack) 2 and (stack[-1] stack[-2]) % 2 0: stack.pop() stack.pop() return stack5.3 Python实现注意事项列表性能Python列表的append/pop操作都是O(1)时间复杂度类型检查Python是动态类型语言可以添加类型注解提高代码质量大数处理Python的整数没有大小限制不用担心溢出问题切片操作合理使用切片可以简化代码但可能影响性能6. 三种语言实现对比6.1 语法差异对比特性JavaJavaScriptPython堆栈实现Stack/Deque类数组列表添加元素push()push()append()移除元素pop()pop()pop()查看栈顶peek()array[length-1]list[-1]大小检查size()length属性len()函数6.2 性能对比对于同样的算法三种语言的性能特点Java静态编译语言执行速度最快但需要编译步骤JavaScriptJIT编译现代引擎优化很好但在不同环境中性能可能有差异Python解释执行通常比前两者慢但开发效率高6.3 适用场景对比Java适合大型应用、企业级开发需要高性能和类型安全的场景JavaScript适合Web前端、服务端(Node.js)需要跨平台运行的场景Python适合快速原型开发、数据分析、脚本编写等场景7. 常见问题与解决方案7.1 堆栈溢出问题问题描述当输入数组非常大时某些语言的递归实现可能导致堆栈溢出。解决方案始终使用迭代而非递归实现对于特别大的数据集考虑分批处理在Java中增加JVM堆栈大小-Xss参数7.2 数字溢出问题问题描述在Java和JS中大数相加可能导致整数溢出。解决方案在Java中使用long代替int在JS中使用BigInt类型在Python中不需要特别处理自动支持大整数7.3 边界条件处理常见错误空输入数组未处理单个元素数组处理不正确连续多个消除操作处理不当测试用例建议# 空数组 assert remaining_numbers([]) [] # 单个元素 assert remaining_numbers([1]) [1] # 全部消除 assert remaining_numbers([2,4,6,8]) [] # 无消除 assert remaining_numbers([1,3,5,7]) [1,3,5,7] # 混合情况 assert remaining_numbers([1,3,4,2,5,8]) [1,3,5]8. 实际应用场景扩展8.1 游戏开发中的应用这种堆栈消除逻辑常见于各种消除类游戏中比如泡泡龙游戏相同颜色的泡泡消除连连看相同图案的卡片消除俄罗斯方块完整行的消除8.2 编译器中的应用编译器在处理语法分析时也常用到类似的堆栈操作括号匹配检查HTML标签嵌套检查函数调用栈跟踪8.3 金融交易系统中的应用在订单匹配系统中买入价和卖出价匹配时执行交易限价订单的撮合逻辑交易流水的时间序列处理9. 算法变体与进阶练习9.1 变体一三元组消除修改规则当栈顶三个元素满足某种条件时消除如和为3的倍数def remaining_numbers_triple(nums): stack [] for num in nums: stack.append(num) while len(stack) 3 and (stack[-1] stack[-2] stack[-3]) % 3 0: stack.pop() stack.pop() stack.pop() return stack9.2 变体二相邻相同元素消除修改规则消除相邻的相同元素无论数量function remainingNumbersSame(nums) { const stack []; for (const num of nums) { if (stack.length 0 stack[stack.length-1] num) { stack.pop(); } else { stack.push(num); } } return stack; }9.3 变体三多条件消除修改规则同时支持多种消除条件如和为偶数或差为质数public static int[] remainingNumbersMultiCondition(int[] nums) { DequeInteger stack new ArrayDeque(); for (int num : nums) { stack.push(num); while (stack.size() 2) { int top stack.pop(); int second stack.pop(); if (isConditionMet(top, second)) { continue; } else { stack.push(second); stack.push(top); break; } } } // 转换为数组返回 return stack.stream().mapToInt(i-i).toArray(); } private static boolean isConditionMet(int a, int b) { return (a b) % 2 0 || isPrime(Math.abs(a - b)); } private static boolean isPrime(int n) { // 质数判断实现 }10. 性能优化与测试10.1 基准测试设计为了比较不同实现的性能可以设计如下测试小数据集(10-100元素)测试基本功能中等数据集(1,000-10,000元素)测试一般性能大数据集(100,000元素)测试极限性能特殊数据集(全消除、无消除)测试边界情况10.2 Java性能优化技巧使用基本类型集合库如Eclipse Collections避免装箱开销对于固定大小的堆栈使用数组实现使用JMH进行精确的微基准测试10.3 JavaScript性能优化技巧使用类型数组(如Int32Array)处理纯数字避免在热循环中创建新对象使用V8引擎的优化模式10.4 Python性能优化技巧使用PyPy代替CPython获得JIT优化对于性能关键部分考虑用Cython实现使用内置函数和列表推导式代替显式循环11. 面试考点分析这道题目在技术面试中经常出现主要考察以下几个方面11.1 基础数据结构理解堆栈的LIFO特性基本操作(push/pop/peek)的时间复杂度堆栈的常见应用场景11.2 算法思维如何将问题分解为堆栈操作循环条件的正确设置边界条件的处理能力11.3 多语言实现能力不同语言中堆栈的实现差异语言特性的合理运用代码风格和最佳实践11.4 问题解决能力对异常情况的处理性能优化的考虑测试用例的设计12. 学习资源推荐12.1 堆栈数据结构《算法导论》经典算法教材详细讲解堆栈及其应用LeetCode大量堆栈相关练习题VisuAlgo可视化堆栈操作的学习网站12.2 语言特定学习Java: Oracle官方文档Effective JavaJavaScript: MDN Web文档Eloquent JavaScriptPython: Python官方文档Fluent Python12.3 算法进阶《编程珠玑》经典算法问题集《算法图解》算法入门好书Codeforces算法竞赛平台提高算法能力13. 开发工具推荐13.1 Java开发工具IntelliJ IDEA智能Java IDEEclipse经典Java开发环境JUnit单元测试框架13.2 JavaScript开发工具VS Code轻量级强大编辑器Chrome DevTools调试利器JestJavaScript测试框架13.3 Python开发工具PyCharm专业Python IDEJupyter Notebook交互式开发环境pytestPython测试框架14. 实际项目应用建议在实际项目中应用此类算法时建议代码可读性添加清晰的注释特别是算法关键部分单元测试编写全面的测试用例覆盖各种边界条件性能监控对于高频调用的场景加入性能监控文档记录记录算法的设计决策和优化点团队评审重要的算法实现应该进行团队代码评审15. 个人实践心得在实际实现这个算法的过程中我发现几点值得分享的经验测试驱动开发先写测试用例再实现代码可以大大提高代码质量性能对比同样算法在不同语言中的性能差异可能很大要根据场景选择合适的语言边界条件算法题的大部分错误都来自边界条件处理不当代码复用对于多语言实现保持算法逻辑一致但适应语言特性持续学习通过这样的练习可以深入理解不同语言的特性和优劣

相关新闻

大模型基准测试全解析:从Opus 5分数看懂模型能力与工程选型

大模型基准测试全解析:从Opus 5分数看懂模型能力与工程选型

最近在跟进大模型技术动态时,发现一个很有意思的现象:各家模型厂商都在发布各种“第一”、“超越”的新闻,但作为开发者,我们往往看得一头雾水。比如,当看到“Epoch AI 新基准测试 Opus 5 得分 59%”这样的标题时&…

2026/9/23 13:29:54 阅读更多 →
构建高效人生系统:从时间管理到能量优化

构建高效人生系统:从时间管理到能量优化

1. 为什么我们需要一个人生系统现代人的生活节奏越来越快,信息过载成为常态。每天要处理工作邮件、社交信息、家庭事务、个人成长等各种事项,大脑就像一台永远在后台运行的老旧电脑,不断被各种弹窗和进程拖慢速度。这就是为什么我们需要建立一…

2026/9/23 21:41:38 阅读更多 →
Unity AsyncOperation深度解析:从异步加载原理到性能优化实战

Unity AsyncOperation深度解析:从异步加载原理到性能优化实战

1. 项目概述:为什么AsyncOperation是Unity性能优化的基石如果你在Unity开发中遇到过场景切换卡顿、资源加载导致游戏帧率骤降,或者UI在加载时完全冻结,那么你大概率已经和AsyncOperation打过照面了。这玩意儿是Unity异步操作的核心抽象&#…

2026/9/23 14:22:26 阅读更多 →

最新新闻

razzle-dev-utils 工具集完全指南:从日志、错误美化到 Loader 查找的 Razzle 开发辅助库

razzle-dev-utils 工具集完全指南:从日志、错误美化到 Loader 查找的 Razzle 开发辅助库

前端构建工具前端构建后端 【免费下载链接】razzle ✨ Create server-rendered universal JavaScript applications with no configuration 项目地址: https://gitcode.com/gh_mirrors/ra/razzle 点击查看 免费下载 本指南以 Razzle 仓库中 packages/razzle-dev-ut…

2026/9/23 23:07:30 阅读更多 →
医疗AI生成PPT的数据安全与完整性保障方案

医疗AI生成PPT的数据安全与完整性保障方案

1. 医疗场景下AI生成PPT的数据安全挑战在医疗信息化快速发展的今天,医护人员使用AI工具辅助制作学术报告、病例讨论PPT已成为普遍现象。某三甲医院统计显示,2023年有78%的临床科室使用过AI生成演示文档。但随之而来的数据安全问题不容忽视——去年国内医…

2026/9/23 23:07:30 阅读更多 →
数据安全与隐私计算技术深度解析与应用实践

数据安全与隐私计算技术深度解析与应用实践

1. 活动背景与核心价值解析这场由云创数安创始人兼总经理白云先生主讲的上海站活动,本质上是一场聚焦数据安全领域的行业深度交流会。作为国内数据安全赛道的早期实践者,白云及其团队在金融级数据加密、企业隐私计算架构等领域有多个标杆案例。活动选址上…

2026/9/23 23:07:29 阅读更多 →
OSPF课程设计:从配通到可验证的路由决策

OSPF课程设计:从配通到可验证的路由决策

简介:本资源是一份面向计算机网络专业本科生的课程设计实践文档,聚焦OSPF路由协议在多局域网互连中的实际应用,帮助学习者系统掌握子网划分、OSPF原理与配置、拓扑设计及Cisco设备实操等核心技能。压缩包为1个1.16MB的Word文档(.d…

2026/9/23 23:07:29 阅读更多 →
使用 PHP 与 AWS SDK 开发 Ceph RGW(S3 兼容)应用:从连接创建到签名 URL 的完整指南

使用 PHP 与 AWS SDK 开发 Ceph RGW(S3 兼容)应用:从连接创建到签名 URL 的完整指南

存储分布式文件系统对象存储后端高可用 【免费下载链接】ceph Ceph is a distributed object, block, and file storage platform 项目地址: https://gitcode.com/gh_mirrors/ce/ceph 点击查看 免费下载 本文以 Ceph 对象网关(RADOS Gateway&#xff0…

2026/9/23 23:07:29 阅读更多 →
星图识别全解析:从几何特征到姿态解算的工程实践

星图识别全解析:从几何特征到姿态解算的工程实践

简介:面向天文观测、航天导航与星图识别应用场景的MATLAB实现工具包,围绕星图识别全流程组织代码,适合需要开展星体特征提取、位置解算或BP网络识别实验的研究人员、工程师与相关专业学生。资源共18个文件,以15个m脚本为主&#x…

2026/9/23 23:06:29 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →