Leetcode 394. Decode String 字符串解码 解题报告

LeetCode 394: 使用栈解码字符串
本文介绍了LeetCode 394题的解题思路,重点是利用栈来解决字符串的解码问题。解题过程中,遇到'['时,将数字和未解码字符串压入栈中;遇到']'时,将栈顶数字与未解码字符串拼接并重复栈顶数字次,然后连接到全局解码字符串。解析过程中注意栈空的条件,标志着当前嵌套解码完成。

1 解题思想

意思是在字符串当中,有一个特殊的格式 — k[S],遇到这种状况,需要把S重复k次,注意是可以嵌套的

在这次解题当中,我是使用了栈的方式,去解决这个问题。分别使用了一个全局的已解码的字符串Builder,另外对于为解码的,使用栈来暂存。

符号’[‘控制进栈,分别进入计数数字和之前尚未解码的字符串
符号’]’控制出站,出栈当前计数,并且将未解码的字符串进行重复,再链接上一个未解码的字符串

注意栈空的时候证明当前嵌套解码完毕,需要添加到全局当中,反之基于暂存。

2 原题

Given an encoded string, return it's decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.

You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.

Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4].

Examples:

s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".

3 AC解

public class Solution {
    public String decodeString(String s) {
        int n = s.length();
        char[] ss = s.toCharArray();
        Stack<Integer> counts = new Stack<Integer>();
        Stack<String> strings = new Stack<String>();
        StringBuilder result = new StringBuilder();
        int count = 0;
        //当前需要解码,但是还没有遇到]暂存的
        String currentString = "";
        for(int i=0;i<n;i++){
            if(ss[i]>='0' && ss[i]<='9'){
                count = count * 10;
                count = count + ss[i] -'0';
            } else if(ss[i] == '['){
                counts.push(count);
                count = 0;
                strings.push(currentString);
                currentString = "";
            }else if(ss[i] >='a' && ss[i]<='z'){
                //注意栈空与否很重要
                if(!counts.isEmpty())
                    currentString += ss[i];
                else result.append(ss[i]);
            } else if(ss[i] == ']'){
                int times = counts.pop();
                if(counts.isEmpty()){
                    for(int j=0;j<times;j++)
                        result.append(currentString);
                     currentString=strings.pop();
                } else {
                    String tmp = "";
                    for(int j=0;j<times;j++)
                        tmp+=currentString;
                    currentString = strings.pop()+tmp;
                }

            }
        }
        return result.toString();
    }
}
LeetCode 394字符串解码问题中,C++递归解决方案的核心在于每次递归要取出数字以及对应括号里的内容,递归完成之后,将其按循环次数添加到结果字符串中。以下是两种不同的C++递归实现代码: 第一种实现方式: ```cpp class Solution { public: string decodeString(string s) { // 题意编码的实现,是递归的过程 int pos = 0; return dfs(s, pos); } // 每次递归要做的事:取出数字,以及对应括号里的内容,递归完成之后,循环次数添加到res中 // 注意点:[ 、]符号的跳过 string dfs(string& s, int& pos) { string res = ""; while (pos < s.size() && s[pos] != ']') { if (isalpha(s[pos])) res += s[pos++]; else if (isdigit(s[pos])) { // 没到数字,就确定完数字向后递归 int cnt = 0; while (isdigit(s[pos])) cnt = cnt * 10 + s[pos++] - '0'; pos++; // 最后一次终止条件在[ , 否则递归时不满足while条件,直接退出 string y = dfs(s, pos); pos++; // pos++用于去除] for (int i = 0; i < cnt; i++) res += y; } } return res; } }; ``` 这种实现方式在`dfs`函数里,利用`while`循环遍历字符串,根据字符是字母还是数字进行不同处理。遇到字母直接添加到结果字符串,遇到数字则先解析出重复次数,递归处理括号内的字符串,最后按次数添加到结果中。 第二种实现方式: ```cpp class Solution { private: int get_digit(string& s, int &index) { int num = 0; while (index < s.length() && isdigit(s[index])) num = num * 10 + s[index++] - '0'; return num; } string get_str(string& s, int &index) { // 递归的出口,前一个很容易想到,后一个作为递归出口的条件,更加方便 if (index >= s.length() || ']' == s[index]) return ""; string str; if (isdigit(s[index])) { // 如果是数字,先获取重复的次数,再获取字符串 int cnt = get_digit(s, index); // 获取重复的次数 index++; // 精髓,跳过'['符号 string temp = get_str(s, index); // 获取下一个字符串 index++; // 精髓,跳过']'符号 while (cnt--) str += temp; // 重复添加字符串 } else { // 如果不是数字,则直接获取字符串 while (isalpha(s[index])) str += s[index++]; } // 返回这一次的结果+后面的结果 return str + get_str(s, index); } public: string decodeString(string s) { int i = 0; return get_str(s, i); } }; ``` 此实现方式通过`get_digit`函数解析重复次数,`get_str`函数进行递归处理。当遇到数字时,先获取重复次数,跳过`[`,递归处理括号内字符串,再跳过`]`,最后按次数添加;遇到字母则直接添加到结果字符串。最终返回当前处理结果与后续递归结果的拼接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值