面试题 03.01. 三合一 - 力扣(LeetCode)

三合一。描述如何只用一个数组来实现三个栈。

你应该实现push(stackNum, value)pop(stackNum)isEmpty(stackNum)peek(stackNum)方法。stackNum表示栈下标,value表示压入的值。

构造函数会传入一个stackSize参数,代表每个栈的大小。

示例1:

输入:
["TripleInOne", "push", "push", "pop", "pop", "pop", "isEmpty"]
[[1], [0, 1], [0, 2], [0], [0], [0], [0]]
 输出:
[null, null, null, 1, -1, -1, true]
说明:当栈为空时`pop, peek`返回-1,当栈满时`push`不压入元素。

示例2:

输入:
["TripleInOne", "push", "push", "push", "pop", "pop", "pop", "peek"]
[[2], [0, 1], [0, 2], [0, 3], [0], [0], [0], [0]]
 输出:
[null, null, null, null, 2, 1, -1, -1]

解题思路

只用一个数组实现3个栈

我们可以把三个栈都放在一个数组中

三合一,棒球比赛问题_数组

class TripleInOne {
    public int[] stack;
    public int[] top;
    public TripleInOne(int stackSize) {
        stack = new int[3 * stackSize];
        top = new int[3];
        for (int i = 0; i < 3; i++) {
            top[i] = i;
        }
    }

三合一,棒球比赛问题_数组_02

此时的下标也相当于长度

public void push(int stackNum, int value) {
    if(top[stackNum] < stack.length) {
        stack[top[stackNum]] = value;
        top[stackNum] = top[stackNum] + 3;
    }
}
public int pop(int stackNum) {
        if(isEmpty(stackNum)) {
            return -1;
        }
        top[stackNum] = top[stackNum] - 3;
        return stack[top[stackNum]];
    }

    public int peek(int stackNum) {
        if(isEmpty(stackNum)) {
            return -1;
        }
        int index = top[stackNum] - 3;
        return stack[index];

    }

    public boolean isEmpty(int stackNum) {
        if(top[stackNum] - 3 < 0) {
            return true;
        }
        return false;
    }
}

682. 棒球比赛

简单

292

相关企业

你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

  1. 整数 x - 表示本回合新获得分数 x
  2. "+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
  3. "D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
  4. "C" - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。

请你返回记录中所有得分的总和。

示例 1:

输入:ops = ["5","2","C","D","+"]
输出:30
解释:
"5" - 记录加 5 ,记录现在是 [5]
"2" - 记录加 2 ,记录现在是 [5, 2]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5].
"D" - 记录加 2 * 5 = 10 ,记录现在是 [5, 10].
"+" - 记录加 5 + 10 = 15 ,记录现在是 [5, 10, 15].
所有得分的总和 5 + 10 + 15 = 30

示例 2:

输入:ops = ["5","-2","4","C","D","9","+","+"]
输出:27
解释:
"5" - 记录加 5 ,记录现在是 [5]
"-2" - 记录加 -2 ,记录现在是 [5, -2]
"4" - 记录加 4 ,记录现在是 [5, -2, 4]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5, -2]
"D" - 记录加 2 * -2 = -4 ,记录现在是 [5, -2, -4]
"9" - 记录加 9 ,记录现在是 [5, -2, -4, 9]
"+" - 记录加 -4 + 9 = 5 ,记录现在是 [5, -2, -4, 9, 5]
"+" - 记录加 9 + 5 = 14 ,记录现在是 [5, -2, -4, 9, 5, 14]
所有得分的总和 5 + -2 + -4 + 9 + 5 + 14 = 27

示例 3:

输入:ops = ["1"]
输出:1

 解题思路

我们可以利用栈来实现

三合一,棒球比赛问题_栈_03

三合一,棒球比赛问题_栈_04

三合一,棒球比赛问题_栈_05

三合一,棒球比赛问题_数组_06

最后遍历栈 记录所有分数之和

代码实现

class Solution {
        public int calPoints(String[] operations) {
            Deque<Integer> stack = new ArrayDeque<>();
            for (String s : operations) {
                if (findInt(s)) {
                    int x = Integer.parseInt(s);
                    stack.push(x);
                }
                if (s.equals("+")) {
                    int num2 = stack.pop();
                    int num = num2 + stack.peek();
                    stack.push(num2);
                    stack.push(num);
                }
                if (s.equals("D")) {
                    stack.push(2 * stack.peek());
                }
                if (s.equals("C")) {
                    stack.pop();
                }
            }
            int ans = 0;
            for (int score : stack) {
                ans += score;
            }
            return ans;
        }

        public boolean findInt(String s) {
            if (s.equals("+") || s.equals("D") || s.equals("C")) {
                return false;
            }
            return true;
        }
    }