华为机试 - 堆栈中的剩余数字
创始人
2024-01-29 20:38:43
0

目录

题目描述

输入描述

输出描述

用例

题目解析

算法源码


题目描述

向一个空栈中依次存入正整数,假设入栈元素 n(1<=n<=2^31-1)按顺序依次为 nx…n4、 n3、n2、 n1, 每当元素入栈时,如果 n1=n2+…+ny(y 的范围[2,x], 1<=x<=1000),则 n1~ny 全部元素出栈,重新入栈新元素 m(m=2*n1)。

如:依次向栈存入 6、 1、 2、 3, 当存入 6、 1、 2 时,栈底至栈顶依次为[6、 1、 2];当存入 3时, 3=2+1, 3、 2、 1 全部出栈,重新入栈元素 6(6=2*3),此时栈中有元素 6;

因为 6=6,所以两个 6 全部出栈,存入 12,最终栈中只剩一个元素 12。

输入描述

使用单个空格隔开的正整数的字符串,如”5 6 7 8″, 左边的数字先入栈,输入的正整数个数为 x, 1<=x<=1000。

输出描述

最终栈中存留的元素值,元素值使用空格隔开,如”8 7 6 5″, 栈顶数字在左边。 6 1 2 3

用例

输入5 10 20 50 85 1
输出1 170
说明5+10+20+50=85, 输入 85 时, 5、 10、 20、 50、 85 全部出栈,入栈 170,最终依次出栈的数字为 1 和 170。
输入6 7 8 13 9
输出9 13 8 7 6
说明
输入1 2 5 7 9 1 2 2
输出4 1 9 14 1
说明

题目解析

这题我们先求出,以每个输入元素为结尾子区间的和,存入dp数组中。如下图dp数组所示:

然后从第1个元素开始遍历(索引0开始),对比arr[i]和dp[i-1],此时

有三种可能:

  • arr[i] === dp[i-1]
  • arr[i] > dp[i-1]
  • arr[i] < dp[i-1]

其中dp[i-1]代表arr数组0~i-1索引元素值的总和。

如果arr[i] > dp[i-1],说明arr数组0~i-1的元素即使全算上,不够arr[i]打,即无法合并。

如果arr[i] === dp[i-1],arr[i]可以和前面0~i-1个数组元素合并。此时我们可以将arr[i]更改为dp[i]的值,即2 * dp[i-1] 或者 2 * arr[i],然后将arr数组的0~i-1索引删除,如下面例子所示

如果arr[i] < dp[i-1],则说明 arr数组 在 0~i-1 中存在子区间的和  可能 等于 arr[i]。

而这个子区间的右边界又必须为i-1,因此我们只能不断退出0~i-1的头部,第一次退出arr[0],然后算arr的1~i-1区间和是否等于arr[i],若不相等,则继续退出头部arr[1],然后算arr的2~i-1的区间和是否等于arr[i],若不相等,处理同上

 若相等,则我们需要将arr[i]的值替换为 2~i-1的区间和 * 2,然后删除arr数组的 2~i-1 子序列。

算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});rl.on("line", (line) => {const arr = line.split(" ").map(Number);console.log(getRemain(arr));
});function getRemain(arr) {const dp = [arr[0]];for (let i = 1; i < arr.length; i++) {dp[i] = arr[i] + dp[i - 1];}for (let i = 1; i < arr.length; i++) {if (arr[i] === dp[i - 1]) {arr[i] = dp[i];arr.splice(0, i);dp.splice(0, i);i = 0;continue;}if (arr[i] < dp[i - 1]) {let right = i - 1;let left = i - 1;while (left >= 1) {let subSum = dp[right] - dp[left - 1];if (subSum > arr[i]) break;if (subSum === arr[i]) {arr[i] *= 2;arr.splice(left, right - left + 1);dp.splice(left, right - left + 1);i = left;break;}left--;}}}return arr.reverse().join(" ");
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...