【数据结构与算法 | 灵神题单 | 栈基础篇】力扣1441, 844, 682

1. 力扣1441:用栈操作构建数组

1.1 题目:

给你一个数组 target 和一个整数 n。每次迭代,需要从  list = { 1 , 2 , 3 ..., n } 中依次读取一个数字。

请使用下述操作来构建目标数组 target :

  • "Push":从 list 中读取一个新元素, 并将其推入数组中。
  • "Pop":删除数组中的最后一个元素。
  • 如果目标数组构建完成,就停止读取更多元素。

题目数据保证目标数组严格递增,并且只包含 1 到 n 之间的数字。

请返回构建目标数组所用的操作序列。如果存在多个可行方案,返回任一即可。

示例 1:

输入:target = [1,3], n = 3
输出:["Push","Push","Pop","Push"]
解释: 
读取 1 并自动推入数组 -> [1]
读取 2 并自动推入数组,然后删除它 -> [1]
读取 3 并自动推入数组 -> [1,3]

示例 2:

输入:target = [1,2,3], n = 3
输出:["Push","Push","Push"]

示例 3:

输入:target = [1,2], n = 4
输出:["Push","Push"]
解释:只需要读取前 2 个数字就可以停止。

提示:

  • 1 <= target.length <= 100
  • 1 <= n <= 100
  • 1 <= target[i] <= n
  • target 严格递增

1.2 思路:

哈希表记录target数组的值,分遇见了和没遇见两种情况讨论。

1.3 题解:

class Solution {
    public List<String> buildArray(int[] target, int n) {
        List<String> list = new LinkedList<>();
        // 用哈希表将数组中的值存起来
        // 如果遇到了,就加入push,否则加入push和pop
        HashSet<Integer> hashset = new HashSet<>();
        for(int i : target){
            hashset.add(i);
        }
        //target[target.length-1]肯定是小于等于n的
        // 所以条件范围用target[target.length-1]限定
        for(int i = 1; i <= target[target.length-1]; i++){
            if(!hashset.contains(i)){
                list.add("Push");
                list.add("Pop");
            }else{
                list.add("Push");
            }
        }
        return list;
    }
}

2. 力扣844:比较含退格的字符串

2.1 题目:

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:

输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。

示例 2:

输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。

示例 3:

输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。

提示:

  • 1 <= s.length, t.length <= 200
  • s 和 t 只含有小写字母以及字符 '#'

进阶:

  • 你可以用 O(n) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?

2.2 思路:

用栈也可以,我用的是StringBuffer的api,主要是equals可以省去了最后的比较过程比较方便和操作都可以调用api来完成。

2.3 题解:

class Solution {
    public boolean backspaceCompare(String s, String t) {
        
        StringBuffer sb1 = new StringBuffer();
        StringBuffer sb2 = new StringBuffer();
        for(int i = 0; i < s.length(); i++){
            char ch1 = s.charAt(i);
            if(ch1 != '#'){
                sb1.append(ch1);
            }else{
                // 这里防止当sb为空的时候遇见#,deleteCharAt会报错
                if(sb1.length()-1 >= 0){
                    sb1.deleteCharAt(sb1.length()-1);
                }
            }
            
        }
        for(int i = 0; i < t.length(); i++){
            char ch2 = t.charAt(i);
            if(ch2 != '#'){
                sb2.append(ch2);
            }else{
                if(sb2.length()-1 >= 0){
                    sb2.deleteCharAt(sb2.length()-1);
                }
                
            }
        }
        return sb1.toString().equals(sb2.toString());

    }
}

3. 力扣682:棒球比赛

3.1 题目:

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

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 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

提示:

  • 1 <= ops.length <= 1000
  • ops[i] 为 "C""D""+",或者一个表示整数的字符串。整数范围是 [-3 * 104, 3 * 104]
  • 对于 "+" 操作,题目数据保证记录此操作时前面总是存在两个有效的分数
  • 对于 "C" 和 "D" 操作,题目数据保证记录此操作时前面总是存在一个有效的分数

3.2 思路:

典型的栈的问题,用栈记录合适的数字,然后依据题目判断即可。

3.3 题解:

class Solution {
    public int calPoints(String[] operations) {
        Deque<Integer> stack = new LinkedList<>();

        for(String s : operations){
            if (s.equals("C")){
                stack.pop();
            }else if (s.equals("D")){
                stack.push(stack.peek()*2);
            }else if (s.equals("+")){
                int i = stack.pop();
                int sum = i + stack.peek();
                stack.push(i);
                stack.push(sum);
            }else{
                // 如果是数字就加入
                stack.push(Integer.parseInt(s));
            }
        }
        int sums = 0;
        for(int i : stack){
            sums += i;
        }
        return sums;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值