堆栈中的剩余数字 - 华为OD机试真题(Java 题解)

华为OD机试题库《C++》限时优惠 9.9

华为OD机试题库《Python》限时优惠 9.9

华为OD机试题库《JavaScript》限时优惠 9.9

针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。

看不懂有疑问需要答疑辅导欢迎私VX: code5bug

华为OD机试真题

题目描述

向一个空栈中依次存入正整数,假设入栈元素 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

示例1

输入:
5 10 20 50 85 1

输出:
1 170

说明:
5+10+20+50=85, 输入 85 时, 5、 10、 20、 50、 85 全部出栈,入栈 170,最终依次出栈的数字为 1 和 170。

示例2

输入:
6 7 8 13 9

输出:
9 13 8 7 6

示例3

输入:
1 2 5 7 9 1 2 2

输出:
4 1 9 14 1

题解

这道题属于栈的应用类题目,主要考察对栈数据结构的理解和操作,以及如何利用栈的特性来解决特定问题。题目中涉及到栈的入栈、出栈、以及条件判断下的批量操作。

解题思路

  1. 初始化栈:使用一个数组来模拟栈的操作,维护一个栈顶指针top
  2. 遍历输入数字:依次将每个数字压入栈中。
  3. 检查栈顶条件:每当一个数字入栈后,检查从栈顶向下是否存在连续的元素之和等于当前栈顶元素。具体步骤如下:
    • 从栈顶下方开始,向左遍历栈,累加元素的和。
    • 如果累加和等于当前栈顶元素,则将这些元素全部出栈,并将2 * 栈顶元素重新压入栈中。
    • 重复上述检查过程,直到无法再进行操作为止。
  4. 输出结果:最终栈中剩余的元素即为结果,需要按栈顶到栈底的顺序输出。

时间复杂度

  • 最坏情况下,每次入栈操作可能需要遍历整个栈,而栈的最大长度为O(n),因此总时间复杂度为O(n^2),其中n为输入数字的个数。

空间复杂度

  • 使用了一个栈来存储元素,栈的最大长度为O(n),因此空间复杂度为O(n)

Java

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[] nums = Arrays.stream(scanner.nextLine().split(" "))
                .mapToInt(Integer::parseInt)
                .toArray();

        int n = nums.length;
        int[] stack = new int[n];  // 使用数组模拟栈
        int top = 0;  // 栈顶指针

        for (int num : nums) {
            stack[top] = num;  // 入栈

            boolean go = true;
            while (go) {
                go = false;
                int left = top, sum = 0;
                // 从栈顶向下累加元素
                while (left > 0 && sum < stack[top]) sum += stack[--left];

                // 如果找到连续元素之和等于栈顶元素
                if (sum == stack[top]) {
                    top = left;  // 移动栈顶指针,相当于批量出栈
                    stack[top] = 2 * sum;  // 重新入栈新元素
                    go = true;  // 继续检查
                }
            }
            top++;  // 栈顶指针后移
        }

        // 逆序输出栈中元素
        for (int i = top - 1; i >= 0; i--) {
            System.out.print(stack[i] + (i > 0 ? " " : ""));
        }
    }
}

希望这个专栏能让您熟练掌握算法, 。

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。

你可能感兴趣的:(华为od,java,开发语言,算法,数据结构)