3.栈(三)

题目汇总:https://leetcode-cn.com/tag/stack/

385. 迷你语法分析器中等(不做)

394. 字符串解码(不会做)

402. 移掉K位数字中等(看题解可理解)

456. 132模式中等(不做)

496. 下一个更大元素 I简单[✔]

503. 下一个更大元素 II中等[✔]

591. 标签验证器困难(不做)

636. 函数的独占时间中等(不做)

682. 棒球比赛简单[✔]

394. 字符串解码中等

给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a2[4] 的输入。
示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

思路:

题解https://leetcode-cn.com/problems/decode-string/solution/decode-string-fu-zhu-zhan-fa-di-gui-fa-by-jyd/

class Solution {//执行用时:2 ms, 在所有 Java 提交中击败了55.19%的用户
    public String decodeString(String s) {
        StringBuilder res = new StringBuilder();
        int multi = 0;
        LinkedList<Integer> stack_multi = new LinkedList<>();
        LinkedList<String> stack_res = new LinkedList<>();
        for(Character c : s.toCharArray()) {
            if(c == '[') {
                stack_multi.addLast(multi);
                stack_res.addLast(res.toString());
                multi = 0;
                res = new StringBuilder();
            }
            else if(c == ']') {
                StringBuilder tmp = new StringBuilder();
                int cur_multi = stack_multi.removeLast();
                for(int i = 0; i < cur_multi; i++) tmp.append(res);
                res = new StringBuilder(stack_res.removeLast() + tmp);
            }
            else if(c >= '0' && c <= '9') multi = multi * 10 + Integer.parseInt(c + "");
            else res.append(c);
        }
        return res.toString();

    }
}

402. 移掉K位数字中等

给定一个以字符串表示的非负整数 num,移除这个数中的 k位数字,使得剩下的数字最小。
注意:
num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。
示例 1 :
输入: num = "1432219", k = 3
输出: "1219"
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
示例 2 :
输入: num = "10200", k = 1
输出: "200"
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
示例** 3 :**
输入: num = "10", k = 2
输出: "0"
解释: 从原数字移除所有的数字,剩余为空就是0。

思路:辅助栈
class Solution {
    public String removeKdigits(String num, int k) {
        if(k>=num.length()||num.length()==0)
            return "0";
        Stack<Integer> stack = new Stack<>();
        stack.push(num.charAt(0)-'0');
        for(int i=1;i<num.length();i++){
            while(!stack.isEmpty() && k>0 && stack.peek()>num.charAt(i)-'0'){
                stack.pop();
                k--;
            }
            // 如果n!=0,入栈;如果n==0,但是栈不空,入栈
            if(num.charAt(i)-'0'!=0 || !stack.isEmpty()){
                stack.push(num.charAt(i)-'0');
            }
        }
        //遍历完,但是还没去掉k个数字
        while(k>0){
            k--;
            stack.pop();

        }
        if(stack.isEmpty())
            return "0";
        StringBuilder s = new StringBuilder();
        while(!stack.isEmpty()){
            s.append(stack.pop());
        }
        return s.reverse().toString();//从后往前添加所以我们要逆序
    }
}

496. 下一个更大元素 I简单

给定两个** 没有重复元素** 的数组 nums1nums2 ,其中nums1nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 xnums2 中对应位置的右边的第一个比 **x **大的元素。如果不存在,对应位置输出 -1 。
示例 1:
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
对于num1中的数字4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
对于num1中的数字1,第二个数组中数字1右边的下一个较大数字是 3。
对于num1中的数字2,第二个数组中没有下一个更大的数字,因此输出 -1。
示例 2:
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。

思路:单调栈+哈希表

先对 nums2 中的每一个元素,求出其下一个更大的元素。随后对于将这些答案放入哈希映射(HashMap)中,再遍历数组 nums1,并直接找出答案。维护一个单调栈,栈中的元素从栈顶到栈底是单调不降的。

class Solution {//执行用时:4 ms, 在所有 Java 提交中击败了90.74%的用户
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Stack<Integer> stack = new Stack<>();
        HashMap<Integer,Integer> map = new HashMap<>();
        int[] res = new int[nums1.length];
        for(int num : nums2){
            while(!stack.isEmpty() && stack.peek() < num){
                map.put(stack.pop(), num);
            }
            stack.push(num);
        }
        for(int i=0;i<nums1.length;i++){
            res[i] = map.getOrDefault(nums1[i],-1);
        }
    return res;
    }
}

503. 下一个更大元素 II中等

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例 1:
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
注意: 输入数组的长度不会超过 10000。

思路:单调栈+HashMap

496. 下一个更大元素 I区别在于数组是循环数组,因此复制两倍数组,另外单调栈中存的是数组下标。

class Solution {//执行用时:18 ms, 在所有 Java 提交中击败了36.06%的用户
    public int[] nextGreaterElements(int[] nums) {
        Stack<Integer> stack = new Stack<>();
        HashMap<Integer,Integer> map = new HashMap<>();
        int len = nums.length;
        int[] res = new int[len];

        int[] doubleNums = new int[len * 2];
        //复制一份新的数组
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < len; j++) {
                doubleNums[len * i + j] = nums[j];
            }
        }

        for(int i=0; i < len * 2; i++){
            while(!stack.isEmpty() && doubleNums[stack.peek()] < doubleNums[i]){
                 map.put(stack.pop(), doubleNums[i]);
            }
            stack.push(i);
        }
        for(int i=0;i<len;i++){
            res[i] = map.getOrDefault(i,-1);
        }
    return res;

    }
}

682. 棒球比赛简单

你现在是棒球比赛记录员。
给定一个字符串列表,每个字符串可以是以下四种类型之一:
整数(一轮的得分):直接表示您在本轮中获得的积分数。
"+"(一轮的得分):表示本轮获得的得分是前两轮有效 回合得分的总和。
"D"(一轮的得分):表示本轮获得的得分是前一轮有效 回合得分的两倍。
"C"(一个操作,这不是一个回合的分数):表示您获得的最后一个有效 回合的分数是无效的,应该被移除。
每一轮的操作都是永久性的,可能会对前一轮和后一轮产生影响。
你需要返回你在所有回合中得分的总和。
示例 1:
输入: ["5","2","C","D","+"],输出: 30
解释:
第1轮:你可以得到5分。总和是:5。
第2轮:你可以得到2分。总和是:7。
操作1:第2轮的数据无效。总和是:5。
第3轮:你可以得到10分(第2轮的数据已被删除)。总数是:15。
第4轮:你可以得到5 + 10 = 15分。总数是:30。

思路:辅助栈

保持栈上每个有效回合的值。

class Solution {
    public int calPoints(String[] ops) {
        Stack<Integer> stack = new Stack<>();
        int sum = 0;
        for(String s:ops){
            //表示您获得的最后一个有效 回合的分数是无效的,应该被移除
            if(s.equals("C")){
                sum -= stack.peek();
                stack.pop();
            //表示本轮获得的得分是前一轮有效 回合得分的两倍
            }else if(s.equals("D")){
                sum += 2 * stack.peek();
                stack.push(2*stack.peek());
            //表示本轮获得的得分是前两轮有效回合得分的总和
            }else if(s.equals("+")){
                int top1 = stack.peek() ;
                stack.pop() ;
                int top2 = stack.peek() ;
                sum += top1 + top2 ;
                stack.push(top1) ;
                stack.push(top1 + top2) ;
            }else{//直接表示您在本轮中获得的积分数
                sum += Integer.valueOf(s);
                stack.push(Integer.valueOf(s));
            }
        }
    return sum;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354