AI刷题中和栈相关的题目| 豆包MarsCode AI刷题

102 阅读4分钟

大家好,今天我来继续分享我的豆包MarsCode AI刷题。这次我将通过两个题目来分享一些栈的编程代码小知识。首先是套碗游戏的取碗顺序问题,其次是括号补全问题,这两个问题不是很难,但是也有一些知识需要注意。

第一题-套碗游戏的取碗顺序问题

问题描述

小F正在玩一个套碗的游戏,每个碗都有一个编号,从1到n,它们从大到小被套在一根木棍上。小F只能从木棍上取最上面的碗,每次只能取一个。现在你需要判断给定的取碗顺序是否可行。如果可行,那么返回1,否则返回0。

示例

例如,对于2个碗,取碗的顺序可以是 2 1 或 1 2,这两种顺序都是合法的。而对于3个碗,给定顺序 3 1 2 不可能通过合法操作实现,因此该顺序不可行。

解题步骤

这个问题思路比较简单,先遍历数组的元素进行入栈,然后通过栈的语法规则,来判断这个序列是否是可以得到的。

实现代码

ini
 代码解读
复制代码
public static int solution(int M, int[] a) {
        // write code here
        Stack<Integer> stack=new Stack<>();
        int[] pushed = new int[M];
        for (int i = 0; i < pushed.length; i++) {
            pushed[i]=i+1;
        }
        int j=0;
        int count=0;
        for(int i=0;i< pushed.length;i++){
            stack.push(pushed[i]);
            //出不出栈,取决于等不等于popped
            while(!stack.isEmpty() && stack.peek()==a[j]){

                stack.pop();
                j++;

            }
        }
        if(stack.isEmpty()){
            count=1;
        }
        else{
            count=0;
        }
        return count;
        
    }

细节和知识分享

这段代码是先定义了一个栈,然后以碗的个数为数组的长度,数组的元素依次为1到碗的个数的数字。然后j是对碗及逆行判断的变量,count是结果判断变量。然后遍历这个有序数列,先将元素入栈,然后将栈顶元素和数组a的当前索引元素进行对比,如果相同,则代表能够出栈,最后如果栈是空的,则是一个可行的取碗序列。 这道题是一个比较经典的栈的题目,在做这道题之前没有做过栈的题目,因此做这道题使我对栈的语法有了一定的了解。比如:判断栈空,获取栈顶元素,入栈等语法。

第二题-套碗游戏的取碗顺序问题

问题描述

小R有一个括号字符串 s,他想知道这个字符串是否是有效的。一个括号字符串如果满足以下条件之一,则是有效的:

  1. 它是一个空字符串;
  2. 它可以写成两个有效字符串的连接形式,即 AB
  3. 它可以写成 (A) 的形式,其中 A 是有效字符串。

在每次操作中,小R可以在字符串的任意位置插入一个括号。你需要帮小R计算出,最少需要插入多少个括号才能使括号字符串 s 有效。

示例

当 s = "())" 时,小R需要插入一个左括号使字符串有效,结果为 1

解题步骤

这个问题看上去比较简单,但我刚开始没有想到用栈的方法,想到的是和之后的索引进行判断,判断是否是相对的,以及统计左右括号的个数,总体上都是比较麻烦的。但是用栈就比较简单了,依次将左括号入栈,然后如果是右括号,则判断栈是否是空的,如果不是空的,则代表栈中有相应的左括号与之匹配,则将左括号出栈;如果是空的,则代码有多余的右括号没有匹配。最后将没有匹配的左括号和右括号的个数相加即可。

实现代码

arduino
 代码解读
复制代码
public static int solution(String s) {
        Stack<Character> stack = new Stack<>();
        int insertCount = 0;

        for (char c : s.toCharArray()) {
            if (c == '(') {
                // 如果是左括号,压入栈
                stack.push(c);
            } 
            else if (c == ')') {
                // 如果是右括号,检查栈顶
                if (!stack.isEmpty()) {
                    // 如果栈顶是左括号,弹出栈顶
                    stack.pop();
                } 
                else {
                    // 否则,计数器加一(表示需要插入一个左括号)
                    insertCount++;
                }
            }
        }

        // 栈中剩余的左括号数量就是需要插入的右括号的数量
        return insertCount + stack.size();
    }

细节注意

这道题的难点我认为是想到用栈的方法,这就考察了对栈知识的灵活运用和掌握的程度。由于栈的特点是只能对栈顶元素进行插入和删除,所以我们可以利用这个特点,来将左括号进行入栈操作,如果能够匹配再出栈,不能够匹配最后加和;再对右括号进行判断,判断是否有相应的左括号匹配,有则出栈,可以说非常好地利用了栈的特点。