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,建议多练习,熟能生巧。
相关推荐
变量未定义~1 小时前
单点修改、区间求和(模板)、区间修改,单点查询(模板)
数据结构·算法
LinHenrY12272 小时前
数据结构(二叉树)
数据结构
炸薯条!3 小时前
树--二叉树--堆
数据结构
z200509303 小时前
今日算法(回溯子集)
数据结构·算法·leetcode
Hesionberger3 小时前
巧用异或找出唯一数字(多解)
java·数据结构·python·算法·leetcode
变量未定义~3 小时前
阶乘的约数和、斐波那契数列、数列区间最大值(ST表)
数据结构·算法
晚风予卿云月4 小时前
二分算法练习
数据结构·c++·算法·竞赛·算法随笔
菜菜的顾清寒4 小时前
力扣HOT100(47) 二叉树的层序遍历
算法·leetcode·深度优先
晚风予卿云月5 小时前
《二分答案》算法练习
数据结构·c++·算法·二分·竞赛·算法随笔