071字符串解码

字符串解码

题目链接:https://leetcode.cn/problems/decode-string/description/?envType=study-plan-v2\&envId=top-100-liked

我的解答:

复制代码

分析:有一点点思路想用双栈,但是最后没能实现出来。

看了官方题解后的解答:

复制代码
//方法一:栈操作
//时间复杂度:渐进时间复杂度为 O(S+∣s∣),即 O(S),S为解码后得出的字符串长度。
//空间复杂度:O(S),S为解码后得出的字符串长度。
int ptr;
public String decodeString(String s) {
    LinkedList<String> stack = new LinkedList<>();
    int n = s.length();
    ptr = 0;
    while(ptr < n){
        char cur = s.charAt(ptr);
        //当前字符为数字
        if(Character.isDigit(cur)){
            String digit = getDigit(s);
            stack.addLast(digit);
        }
        //当前字符为字母或'['
        else if(Character.isLetter(cur) || cur == '['){
            stack.addLast(String.valueOf(cur));
            ptr++;
        }
        //当前字符为']'
        else{
            ptr++;
            LinkedList<String> sub = new LinkedList<>();
            //收集子串
            while(!"[".equals(stack.peekLast())){
                sub.addLast(stack.removeLast());
            }
            Collections.reverse(sub);
            //左括号出栈
            stack.removeLast();
            String output = getString(sub);
            int repTime = Integer.parseInt(stack.removeLast());
            StringBuffer t = new StringBuffer();
            //构造字符串
            while(repTime-- > 0){
                t.append(output);
            }
            //将构造好的字符串入栈
            stack.addLast(t.toString());
        }
    }
    return getString(stack);
}

public String getDigit(String s){
    StringBuffer sb = new StringBuffer();
    while(Character.isDigit(s.charAt(ptr))){
        sb.append(s.charAt(ptr++));
    }
    return sb.toString();
}

public String getString(LinkedList<String> temp){
    StringBuffer sb = new StringBuffer();
    for(String str : temp){
        sb.append(str);
    }
    return sb.toString();
}

//方法二:递归
//时间复杂度:渐进时间复杂度为 O(S+∣s∣),即 O(S),S为解码后得出的字符串长度。
//空间复杂度:O(S),S为解码后得出的字符串长度。
int ptr = 0;
public String decodeString(String s) {
    if(ptr == s.length() || s.charAt(ptr) == ']'){
        return "";
    }
    String res = "";
    char cur = s.charAt(ptr);
    //遇到数字,开始解析数字
    if(Character.isDigit(cur)){
        int repTime = getDigit(s);
        //过滤左括号
        ptr++;
        //解析括号内的字符串
        String sub = decodeString(s);
        //过滤右括号
        ptr++;
        //构造字符串
        while(repTime-- > 0){
            res += sub;
        }
    }
    else{
        res += String.valueOf(s.charAt(ptr++));
    }
    return res + decodeString(s);
}

public int getDigit(String s){
    int repTime = 0;
    while(Character.isDigit(s.charAt(ptr))){
        repTime = repTime * 10 + (s.charAt(ptr++) - '0');
    }
    return repTime;
}

分析:

​ 1、方法一的解题思路:用LinkedList模拟栈,方便从栈底往栈顶遍历。遍历字符串s,若遇到数字则获取数字并入栈;若遇到字母或左括号,直接入栈;若遇到右括号,开始收集和处理当前括号中的字符串,重复此操作直到遍历完字符串s,最后栈中从栈底到栈顶的字符串拼接起来就是解码后的字符串。此方法第一需要明确,我们需要从栈底往栈顶遍历元素,所以就不能直接使用封装好的栈结构,只能自己模拟栈;第二,此方法涉及到许多API的调用,我还不太熟悉这些API;第三,当出现数字时,可能有连续多个数字字符组成一个数字。

​ 2、方法二的解题思路:采用递归方法构造子串。如果当前位置为数字位,那么后面一定包含一个用方括号表示的字符串,即属于这种情况:k... ,我们先解析出这个数字,然后递归构造括号中的子串,最后根据数字构造出解析后的子串,我们把 k... 解析结束后,再次调用递归函数,解析右括号右边的内容。

总结

  • 本题主要有两种解题方法,分别为栈操作、递归。思路不难想到,但实现起来较为复杂,细节较多,涉及许多字符和字符串相关的API,建议多练习,熟能生巧。
相关推荐
noipp19 小时前
推荐题目:洛谷 P5843 [SCOI2012] Blinker 的噩梦
c语言·数据结构·c++·算法·游戏·洛谷·luogu
冻柠檬飞冰走茶19 小时前
PTA基础编程题目集 7-20 打印九九口诀表(C语言实现)
c语言·开发语言·数据结构·算法
Hi李耶20 小时前
【LeetCode】9-回文数
算法·leetcode·职场和发展
红叶舞20 小时前
基于线段树的数据结构
数据结构·python·算法
断点之下20 小时前
从“理扑克牌”到“分组优化”——直接插入排序与希尔排序详解
数据结构·算法·排序算法
起个破名想半天了20 小时前
算法与数据结构之DFS深度优先遍历
数据结构·算法·深度优先
鱼子星_21 小时前
【C++】深入剖析list:list及其双向迭代器实现
开发语言·数据结构·c++·笔记·stl·list
江屿风1 天前
【C++笔记】【二叉搜索树】流食般投喂
开发语言·数据结构·c++·笔记
海绵天哥1 天前
LeetCode Hot 100 | 链表(下)· 分组翻转与设计(C++ 题解)
c++·leetcode·链表
爱吃提升1 天前
MATLAB矩阵运算完全指南:从生成到索引操作
数据结构·matlab·矩阵