leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 4 】2021-09-13 - 394. 字符串解码 #13

Open azl397985856 opened 3 years ago

azl397985856 commented 3 years ago

394. 字符串解码

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/decode-string/

前置知识

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[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"

52HzEcho commented 3 years ago
/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function (s) {
    let stack = [], num = '', str = '';
    for (let i of s) {
        if (/^[0-9]+.?[0-9]*$/.test(i)) { //如果是数字
            num += i
        } else if (i == '[') {  //遇到下一个的开头 入栈
            stack.push({
                num: num,
                str: str
            })
            num = '';
            str = '';
        } else if (i == ']') { //出栈
            let top = stack.pop()
            str = top.str + str.repeat(top.num)
        } else { // 如果是字母
            str += i
        }
    }
    return str
};
ningli12 commented 3 years ago

思路

代码

public class Solution {
    public String decodeString(String s) {
        String res = "";
        Stack<Integer> countStack = new Stack<>();
        Stack<String> resStack = new Stack<>();
        int idx = 0;
        while (idx < s.length()) {
            Character c = s.charAt(idx);
            if (Character.isDigit(c)) {
                int count = 0;
                while (Character.isDigit(c)) {
                    count = 10 * count + (c - '0');
                    idx++;
                }
                countStack.push(count);
            }
            else if (c == '[') {
                resStack.push(res);
                res = "";
                idx++;
            }
            else if (c == ']') {
                StringBuilder temp = new StringBuilder (resStack.pop());
                int repeatTimes = countStack.pop();
                for (int i = 0; i < repeatTimes; i++) {
                    temp.append(res);
                }
                res = temp.toString();
                idx++;
            }
            else {
                res += s.charAt(idx++);
            }
        }
        return res;
    }
}

时间复杂度

peteruixi commented 3 years ago

思路

类似题目

  1. Ternary Expression Parser

从后往前遍历获取最完整的substring

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack=[]
        i = len(s)-1
        while i>=0:
            # If value is not a digit, append all the character
            if not s[i].isdigit():
                stack.append(s[i])
                i-=1
            else:
                # If value is a digit, get the value
                num=''
                while i>=0 and s[i].isdigit():
                    num=s[i]+num
                    i-=1
                # Find the substring, by popping all bracket characters
                sub=''
                while stack[-1]!=']':
                    tmp=stack.pop()
                    if tmp!='[':
                        sub+=tmp
                stack.pop()
                sub=int(num)*sub # Perfrom recurring substring
                stack.append(sub) 
        stack.reverse()
        return ''.join(stack)

复杂度分析

lxy030988 commented 3 years ago

思路

代码 js

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function (s) {
  let stack = [],
    str = [],
    res = '',
    num = 0
  for (const char of s) {
    if (char == '[') {
      stack.push(num)
      str.push(res)
      res = ''
      num = 0
    } else if (char == ']') {
      res = str.pop() + res.repeat(stack.pop())
    } else if (!isNaN(char)) {
      num = num * 10 + Number(char)
    } else {
      res += char
    }
  }
  return res
}

复杂度分析

xy147 commented 3 years ago

思路

栈的思路去实现

js代码

function decodeString(S) {
    let stack = [];
    let numstr = '';
    for (let s of S) {
        if (Number.isInteger(+s)) {
            numstr += s;
            continue;
        }
        if (numstr) {
            stack.push(+numstr);
            numstr = '';
        }
        if (s != ']') {
            stack.push(s);
            continue;
        }
        let str = '';
        while (stack.length && stack.slice(-1) != '[') {
            let top = stack.pop();
            top += str;
            str = top;
        }
        stack.pop();
        let count = +stack.pop();
        let pushStr = str.repeat(count);  
        stack.push(pushStr);
    }
    return stack.join('');
}

复杂度分析

V-Enzo commented 3 years ago

思路

维护两个栈去存储字符和数字。 比较困难的是在碰到']'的时候,去字符串顶获取当前已经保存的字符,重复k遍后加到栈顶。 然后把栈顶的元素赋给cur_str,弹出字符串的栈顶元素。 最终的结果就是保留在cur_str中。

class Solution {
public:
    string decodeString(string s) {
          int s_len = s.size();
        stack<int> numstack;
        stack<string> strstack;
        int num = 0;
        string cur_str="";
        string res = "";
        for(int i = 0; i < s_len; i++) {
            if(s[i]>='0' && s[i]<='9') {
                num = 10*num + s[i]-'0';
            }
            else if((s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<'Z')) {
                cur_str += s[i];
                // cout<< cur_str;
            }
            else if(s[i]=='['){
                strstack.push(cur_str);
                numstack.push(num);
                num = 0;
                cur_str="";
            }
            else if(s[i]==']'){
                int k = numstack.top();
                numstack.pop();
                for(int j = 0; j <k; j++){
                    strstack.top() += cur_str;
                }
                cur_str = strstack.top();
                strstack.pop();

            }
    }
    return cur_str;
    }
};

复杂度分析

时间复杂度:O(N) 空间复杂度:O(N)

yan0327 commented 3 years ago

思路: 用两个堆栈,当遇到数字,数字*10累加。遇到'[',将数字压入数字栈,字符串压入字符串栈。遇到']'将重复次数提出来,将]前的字符串重复拼接,除此之外就是继续拼接现有字符串。

关键:strings.Repeat 调用 从string 获取字符串 , string(s[i]) 特别是string 获取单个字符,就string(s[i]) 若有数字就 strconv.Atoi

代码:

func decodeString(s string) string {
    stack1 := []int{}
    stack2 := []string{}
    byte := ""
    count := 0
    for i:=0; i < len(s); i++{
        if s[i] >= '0' && s[i] <= '9'{
            n, _ := strconv.Atoi(string(s[i]))
            count = count *10 + n
        }else if s[i] == '['{
            stack1 = append(stack1, count)
            count = 0
            stack2 = append(stack2, byte)
            byte = ""
        }else if s[i] == ']'{
            num := stack1[len(stack1)-1]
            stack1 = stack1[:len(stack1)-1]
            out := stack2[len(stack2)-1]
            stack2 = stack2[:len(stack2)-1]
            byte = string(out) + strings.Repeat(byte, num) 
        }else{
            byte += string(s[i])
        }
    }
    return byte
}

时间复杂度:O(n) 空间复杂度:O(n)

PearlCoastal commented 3 years ago

思路

递归。

  1. "[": 开启新的一轮递归。 并且生成字符串。

  2. "]": 返回字符串内容, 并结束当前字符串。

代码

class Solution:
    def decodeString(self, s: str) -> str:

        def dfs(position: int):

            res = ""
            multi_round = 0

            while position < len(s):

                if '0' <= s[position] <= '9':
                    multi_round = multi_round*10 + int(s[position])

                elif s[position] == '[':
                    position, tmp = dfs(position + 1)
                    res += multi_round * tmp
                    multi_round = 0

                elif s[position] == ']':
                    return position, res

                else:
                    res += s[position]

                position += 1
            return res

        return dfs(0)

复杂度分析

ff1234-debug commented 3 years ago

思路

利用string ,栈完成,栈用于括号匹配和保存运算完成后的结果

代码 C++

class Solution {
public:
string decodeString(string s) 
{
stack<string> q;
int n=s.size();
string num="",str="",ans="";
for(int i=0;i<n;i++)
{
if(s[i]>='0'&&s[i]<='9') num+=s[i];
else
{
if(num!="")
{
q.push(num);
num="";
}
if(s[i]=='['||(s[i]>='a'&&s[i]<='z')) 
{
str+=s[i];
q.push(str);
str="";
}
else if(s[i]==']')
{
string t="";
string cmp="[";
while(q.top()!=cmp)
{
t=q.top()+t;
q.pop();
}
q.pop();
int m=stoi(q.top());
string k=t;
for(int j=0;j<m-1;j++)
t+=k;
q.pop();
q.push(t);
}
}
}
string t2="";
while(!q.empty())
{
t2=q.top()+t2;
q.pop();
}
ans+=t2;
return ans;
}
};

复杂度分析

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)
Bruce-Young233 commented 3 years ago

思路

建立一个空字符串来储存遍历过的字母,遇到左括号,就将之前的字符串和数字存到一个临时的栈中,遇到右括号时取出,之后按照规则进行连接

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        str_new = ''
        num = 0
        for i in s:
            if i.isdigit():
                num = num * 10 + int(i)  # 处理连续数字
            elif i.isalpha():
                str_new += i  # 将不在括号内的字母存为一个新的字符串
            elif i == '[':
                stack.append((str_new, num))  # 遇到左括号,将之前的字符串和数字存起来
                str_new, num = '', 0  # 重新初始化
            else:
                str_old, num_cur = stack.pop()  # 遇到右括号,取出之前的字符串和数字
                str_new = str_old + num_cur * str_new  # 重复新的字符串,并与之前的字符串相连
        return str_new

复杂度分析

kbfx1234 commented 3 years ago

394. 字符串解码

// 9-13 cpp 栈
class Solution {
public:
    string decodeString(string s) {
        stack<int> nums;
        stack<string> let;
        int num = 0;
        string res = "";
        for (auto i : s) {
            if (i >= '0' && i <= '9') {
              // 注意多位数
                num = num * 10 + i - '0';
            }
            else if (i == '[') {
                nums.push(num);
                num = 0;
                let.push(res);
                res = "";
            }
            else if (i == ']') {
                int k = nums.top();
                nums.pop();
                string temp = let.top();
                for (int i = 0; i < k; i++) {
                    temp += res;
                }
                res = temp;
                let.pop();
            }
            else {
                res += i;
            }
        }
        return res;
    }
};

时间复杂度: O(n)

空间复杂度: O(n)

leige635539766 commented 3 years ago

思路:

根据栈的特点 先进后出 还有括号的判断 在讲义中有提到

代码

class Solution:

    def __init__(self, S):
        self.S = S

    def RecodeString(self):
        stack = []
        result = ""
        for c in self.S:
            if c == ']':
                reStr = ''
                reCount = ''
                while stack and stack[-1] != '[':
                    reStr = stack.pop() + reStr

                stack.pop()   
                while stack and stack[-1].isnumeric():
                    reCount = stack.pop() + reCount
                stack.append(reStr * int(reCount))
            else:
                stack.append(c)

        return result.join(stack)

时间复杂度分析:

O(N) N为输入的数组长度

babbomax98 commented 3 years ago

思路

定义一个数值记录[前的倍数,再定义一个记录[]中的字符串,当遇到]时,执行一个循环将中括号中的字符串遍历输出其的倍数次,如果字符串大于0或者小于9且不在括号里边的时候,就证明前面的数字不是个位数,需要相乘相加,得到多位数正确的值,

代码


class Solution {
    public String decodeString(String s) {
        StringBuilder res= new StringBuilder();
        int no=0;
        LinkedList<Integer> stack_no=new LinkedList<>();
        LinkedList<String> stack_res=new LinkedList<>();
        for(Character c:s.toCharArray()){
            if(c=='['){
                //记录倍数
                stack_no.addLast(no);
                //开始在尾部添加新遍历到的元素
                stack_res.addLast(res.toString());
                no=0;
                res=new StringBuilder();
            }else if(c==']'){
                StringBuilder tmp=new StringBuilder();
                int tmo_no=stack_no.removeLast();
                for(int i=0;i<tmo_no;i++){
                    tmp.append(res);
                }
                res=new StringBuilder(stack_res.removeLast()+tmp);
            }else if(c>='0'&&c<='9'){
                no=no*10+Integer.parseInt(c+"");
            }else
                res.append(c);
        }
    return res.toString();
    }
}

复杂度分析

时间复杂度O(N)

freedom0123 commented 3 years ago
class Solution {
    public String decodeString(String s) {
        //定义结果
        StringBuffer buffer = new StringBuffer();
        //用来 定义字符栈
        LinkedList<String> listString = new LinkedList<>();
        // 用来定义数字栈
        LinkedList<Integer> listInt = new LinkedList<>();
        for(int i = 0;i<s.length();){
            if(s.charAt(i)!=']'){
                char a = s.charAt(i);
                if(a>'9' || a<'0'){
                    //进入字符栈中
                    listString.add(a+"");
                    i++;
                }else{
                    //就是数字,进入数字栈中
                    int j  = i+1;
                    int tem = a-'0';
                    while(s.charAt(j)<='9' && s.charAt(j)>='0' && j<s.length()){
                        tem = tem *10 + (s.charAt(j)-'0');
                        j++;
                    }
                    i = j;
                    listInt.add(tem);
                }
            }else{
                //用来取出字符栈中的元素
                String temString = new String();
                //用来拿出栈顶的数字
                int temInt = listInt.getLast();
                listInt.removeLast();
                // 循环拿出 字符
                while(!listString.isEmpty() && !listString.getLast().equals("[")){
                    temString = listString.getLast()+temString;
                    listString.removeLast();
                }
                listString.removeLast();
                StringBuffer sb = new StringBuffer();
                for(int k = 1;k<=temInt;k++){
                    sb.append(temString);
                }
                //如果说listInt不是空的,就将结果压在listString栈中
                if(!listInt.isEmpty()){
                    listString.add(sb.toString());
                }else{
                    //反之,加到结果中
                    String ss = "";
                    while(!listString.isEmpty()){
                        ss = listString.getLast()+ss;
                        listString.removeLast();
                    }
                    buffer.append(ss);
                    buffer.append(sb);
                }
                i++;
            }
        }
        if(!listString.isEmpty()){
            for(int i =0;i<listString.size();i++){
                buffer.append(listString.get(i));
            }
        }
        return buffer.toString();
    }
}
xiezhengyun commented 3 years ago

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
  var strStack = []
  var numStack = []
  var num = ''
  var res = ''
  for(let c of s){
    if (!isNaN(c)) { //是数字
      num += c
      //1位数以上的数字,不能立即入栈
    } else if (c === '[') { //[ 字符串入栈 , 数字也入栈
      strStack.push(res)
      res = ''
      numStack.push(num)
      num = ''
    } else if (c === ']') { // 双出栈
      var times = numStack.pop()
      var str = strStack.pop()
      res = str + res.repeat(times)
    } else {
      res += c
    }
  }
  return res
};

复杂度

N是字符串s解码后新字符串的长度,S是字符串s的长度

GReyQT commented 3 years ago

思路

还未解答出来,明天继续

cpp

class Solution {
public:
    string decodeString(string s) {
        vector<int> count;
        vector<int> flag;    //括号的下标

        vector<vector<string>> str;//处理多重括号

        int size = s.size();
        for(int i=0; i<size; ++i)
        {
            if(isdigit(s[i]))
            {
                count.push_back(s[i]);
                flag.push_back(++i);    //[的下标
                vector<string> f{"["};
                str.push_back(f);
            }
            else if(s[i] ==']')
            {
                string in;
                for(int j=flag.back(); j<i; ++j)//获取[]中的字符
                {
                    in.push_back();
                }

                string temp;
                for(int j=0; j<count.back(); ++j)//翻倍
                {
                    temp.append(in);
                }

            }
            else
            {

            }

        }
        return res;
    }
};

复杂度

maxyzli commented 3 years ago
class Solution {
public:
    string decodeString(string s) {
          int s_len = s.size();
        stack<int> numstack;
        stack<string> strstack;
        int num = 0;
        string cur_str="";
        string res = "";
        for(int i = 0; i < s_len; i++) {
            if(s[i]>='0' && s[i]<='9') {
                num = 10*num + s[i]-'0';
            }
            else if((s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<'Z')) {
                cur_str += s[i];
                // cout<< cur_str;
            }
            else if(s[i]=='['){
                strstack.push(cur_str);
                numstack.push(num);
                num = 0;
                cur_str="";
            }
            else if(s[i]==']'){
                int k = numstack.top();
                numstack.pop();
                for(int j = 0; j <k; j++){
                    strstack.top() += cur_str;
                }
                cur_str = strstack.top();
                strstack.pop();

            }
    }
    return cur_str;
    }
};
ymkymk commented 3 years ago

思路

两个列表,一个记录数字(即倍数),一个记录字母

代码

``

public class Solution {

        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();
    }
}

复杂度分析

时间复杂度:O(N),一次遍历 s; 空间复杂度:O(N),辅助栈在极端情况下需要线性空间

wanghuaikuan commented 3 years ago

1.思路

本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。

①构建辅助栈 stack, 遍历字符串 s 中每个字符 c;

②当 c 为数字时,将数字字符转化为数字 multi,用于后续倍数计算;

③当 c 为字母时,在 res 尾部添加 c;

④当 c 为 [ 时,将当前 multi 和 res 入栈,并分别置空置 00:

记录此 [ 前的临时结果 res 至栈,用于发现对应 ] 后的拼接操作; 记录此 [ 前的倍数 multi 至栈,用于发现对应 ] 后,获取 multi × [...] 字符串。 进入到新 [ 后,res 和 multi 重新记录。

⑤当 c 为 ] 时,stack 出栈,拼接字符串 res = last_res + cur_multi * res,其中:

last_res是上个 [ 到当前 [ 的字符串,例如 "3[a2[c]]" 中的 a; cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 "3[a2[c]]的2.

2.代码

class Solution {
public:
    string decodeString(string s) {
        int n=s.size();
        vector<int> numS;
        vector<string> charS;
        int a=0;
        string ret;
        for(int i=0;i<n;i++){
            if(isdigit(s[i])){
               a=a*10+s[i]-'0';
            }else if( s[i]=='['){
                numS.push_back(a);
                string tmp;
                charS.push_back(tmp);
                a=0;
            }else if( s[i]==']'){
                int num=numS.back();
                string s1=charS.back();
                charS.pop_back();
                if(charS.size())
                {
                    for(int i=0; i< num; i++){
                        charS.back() +=s1;
                    }   
                }else {
                    for(int i=0; i< num; i++){
                        ret +=s1;
                    }              
                }
                numS.pop_back();
            }else{
                if(charS.size()){
                    charS[charS.size()-1].push_back(s[i]);
                }else{
                    ret.push_back(s[i]);   
                }
            }
        }
        return ret;
    }
};

3.复杂度

遍历一遍s需要的时间为O(s.size());

shenzhengkang commented 3 years ago

1.思路 本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。 ①构建辅助栈 stack, 遍历字符串 s 中每个字符 c; ②当 c 为数字时,将数字字符转化为数字 multi,用于后续倍数计算; ③当 c 为字母时,在 res 尾部添加 c; ④当 c 为 [ 时,将当前 multi 和 res 入栈,并分别置空置 00: 记录此 [ 前的临时结果 res 至栈,用于发现对应 ] 后的拼接操作; 记录此 [ 前的倍数 multi 至栈,用于发现对应 ] 后,获取 multi × [...] 字符串。 进入到新 [ 后,res 和 multi 重新记录。

⑤当 c 为 ] 时,stack 出栈,拼接字符串 res = last_res + cur_multi * res,其中: last_res是上个 [ 到当前 [ 的字符串,例如 "3[a2[c]]" 中的 a; cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 "3[a2[c]]的2.

2.代码 class Solution { public: string decodeString(string s) { int n=s.size(); vector numS; vector charS; int a=0; string ret; for(int i=0;i<n;i++){ if(isdigit(s[i])){ a=a*10+s[i]-'0'; }else if( s[i]=='['){ numS.push_back(a); string tmp; charS.push_back(tmp); a=0; }else if( s[i]==']'){ int num=numS.back(); string s1=charS.back(); charS.pop_back(); if(charS.size()) { for(int i=0; i< num; i++){ charS.back() +=s1; }
}else { for(int i=0; i< num; i++){ ret +=s1; }
} numS.pop_back(); }else{ if(charS.size()){ charS[charS.size()-1].push_back(s[i]); }else{ ret.push_back(s[i]);
} } } return ret; } }; 3.复杂度 遍历一遍s需要的时间为O(s.size());

wenlong201807 commented 3 years ago

解题思路

使用栈结构,
滑动窗口模型判断一个完整的数字
字符串乘法
倒叙叠加字符串

代码块


function checkRate(input) {
  var re = /^[0-9]+.?[0-9]*/;
  //判断字符串是否为数字//判断正整数/[1−9]+[0−9]∗]∗/;//判断字符串是否为数字//判断正整数/[1−9]+[0−9]∗]∗/
  return re.test(input);
}
var decodeString = function (s) {
  const stack = [];
  let numStr = '';
  for (let i = 0; i < s.length; i++) {
    if (checkRate(s[i])) {
      numStr += s[i];
      continue;
    } else {
      if (numStr) stack.push(numStr);
      numStr = '';

      if (s[i] !== ']') {
        stack.push(s[i]);
      } else {
        let tempStr = '';
        while (stack.length) {
          const curStr = stack.pop();
          if (curStr !== '[') {
            tempStr = curStr + tempStr;
          } else {
            break;
          }
        }
        let curNum = stack.pop();
        stack.push(tempStr.repeat(curNum));
      }
    }
  }
  return stack.join('');
}

时间复杂度和空间复杂度

Zhang6260 commented 3 years ago

JAVA版本

思路:

定义一栈来存储计算,当前字符不为 ‘】‘就直接存入到栈中,当前的字符为’]‘的时候,则就是要出栈的时候,直到栈顶为’[’,然后将‘[’出栈,再判断栈顶是否为数字(注意存在的数字可能是二位数一样),再通过所得的字符转,算出字符串并进行入栈,再取下一位字符进行判断,重复以上的操作。

class Solution {
    public String decodeString(String s) {
        int n=s.length();
        int i=0;
        Stack<String> stack=new Stack<String>();
        while(i<n){
            char temp=s.charAt(i);
            if(temp!=']'){
                stack.push(temp+"");
            }else{
                String temp_string = "";
                String temp_string2= "";
                int  count=0;
                while(fun(stack.peek())){    //取到栈顶为【为止
                    temp_string=stack.pop()+temp_string;
                }
                stack.pop();//[出栈
                double  num=0.0;
                while(!stack.isEmpty()){   //继续从栈中取 直到栈顶不为数字为止
                    if(Character.isDigit(stack.peek().charAt(0))){
                        count=Integer.parseInt(stack.peek())*(int)Math.pow(10.0,num)+count;
                        num++;
                    }else{
                        break;
                    }
                    stack.pop();
                }
                while (count>0){
                    temp_string2 += temp_string;
                    count--;
                }
                stack.push(temp_string2);
            }
            i++;
        }
        String res="";
        while (!stack.isEmpty()){
           res=stack.pop()+res;
        }
        return res;
    }
    public  boolean fun(String s){
            if(s.length()>1)return true;
            if(s.equals("["))return false;

            return true;
        }
}

时间复杂度:(有点分析不来。。。)

空间复杂度:O(N)

summer506hai commented 3 years ago

解题思路

if name == 'main': print(decodeString("3[a2[c]]"))

EggEggLiu commented 3 years ago

思路

准备两个栈,一个存数字,一个存翻倍字符串

代码

class Solution {
public:
    string getDigits(string &s, size_t &ptr) {
        string ret = "";
        while (isdigit(s[ptr])) {
            ret.push_back(s[ptr++]);
        }
        return ret;
    }

    string getString(vector <string> &v) {
        string ret;
        for (const auto &s: v) {
            ret += s;
        }
        return ret;
    }

    string decodeString(string s) {
        vector <string> stk;
        size_t ptr = 0;

        while (ptr < s.size()) {
            char cur = s[ptr];
            if (isdigit(cur)) {
                // 获取一个数字并进栈
                string digits = getDigits(s, ptr);
                stk.push_back(digits);
            } else if (isalpha(cur) || cur == '[') {
                // 获取一个字母并进栈
                stk.push_back(string(1, s[ptr++])); 
            } else {
                ++ptr;
                vector <string> sub;
                while (stk.back() != "[") {
                    sub.push_back(stk.back());
                    stk.pop_back();
                }
                reverse(sub.begin(), sub.end());
                // 左括号出栈
                stk.pop_back();
                // 此时栈顶为当前 sub 对应的字符串应该出现的次数
                int repTime = stoi(stk.back()); 
                stk.pop_back();
                string t, o = getString(sub);
                // 构造字符串
                while (repTime--) t += o; 
                // 将构造好的字符串入栈
                stk.push_back(t);
            }
        }

        return getString(stk);
    }
};

复杂度

时间:O(n)

空间:O(n)

BreezePython commented 3 years ago

解题思路

解法可能过于简单粗暴,时间比较紧先记录下解题

  1. 循环字符串s
  2. 非 "]" 默认全部入栈
  3. 遇到"]"时
    • 维护strs和repeat两个空字符串
    • 先while循环获取所有字符串,条件为stack[-1] != '[' (因为题目明确无异常场景,故此处无需判断栈是否为空)
    • strs = stack.pop() + strs
    • 执行一次stack.pop() 删掉“[”
    • 再次while循环,条件为栈存在且栈顶为数字类型的字符串 (“3[a]”场景,必须判断栈不为空)
    • repeat = stack.pop() + repeat
    • 现在栈中压入int(repeat) * strs即可

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for i in s:
            if i == ']':
                strs = ''
                repeat = ''
                while stack[-1] != '[':
                    strs = stack.pop() + strs
                stack.pop()
                while stack and stack[-1].isdigit():
                    repeat = stack.pop() + repeat
                stack.append(int(repeat) * strs)
                continue
            stack.append(i)
        return ''.join(stack)

复杂度

guangsizhongbin commented 3 years ago

class Solution { public String decodeString(String s) { StringBuilder res = new StringBuilder(); int times = 0; LinkedList multi = new LinkedList<>(); LinkedList stack = new LinkedList<>();

    for(Character c : s.toCharArray()){
       if(c == '[') {
           multi.addLast(times);
           stack.addLast(res.toString());
           times = 0;
           res = new StringBuilder();
       }
       else if(c == ']'){
          StringBuilder tmp = new StringBuilder();
          int cur_multi = multi.removeLast();
          for(int i =0 ;i<cur_multi; i++){tmp.append(res);};
          res = new StringBuilder(stack.removeLast() + tmp);
       }
       else if(c >= '0' && c <= '9'){times = times * 10 + Integer.parseInt(c + "");}
       else res.append(c);
    }
    return res.toString();
}

}

Toms-BigData commented 3 years ago

394. 字符串解码

思路:

定义两个栈char_list,numList. char_list用来存放最后要输出的字符串的数组 num_list用来存放每个s中的数字在char_list中的位置 遍历s 遇到小写字母直接存入 遇到数字时继续读取字符查看数字有几位,拼接成1个数字比如["1","0","0"]转化为“100”存入char_list中,将该位置的值存入num_list中 遇到'['不做处理 遇到']'取出num_list中的栈顶元素(上一个数字的位置),将当前位置的数字取出转化为int(),取出那个位置后的所有char_list中的字符,相乘后存入char_list中 最后以字符串形式输出数组中的所有元素

python3代码

class Solution:
    def decodeString(self, s: str) -> str:
        '字符串列表'
        char_list = [0 for _ in range(10000)]
        char_flag = -1
        num_list = [0 for _ in range(len(s))]
        num_flag = -1
        i = 0
        while i < len(s):
            if 'a' <= s[i] <= 'z':
                char_flag += 1
                char_list[char_flag] = s[i]
            elif '0' <= s[i] <= '9':
                num_length = 1
                while '0' <= s[i + 1] <= '9':
                    num_length += 1
                    i += 1
                head = i - num_length + 1
                tail = i + 1
                a = s[head:tail]
                num_char = ''.join(a)
                char_flag += 1
                char_list[char_flag] = num_char
                num_flag += 1
                num_list[num_flag] = char_flag
            elif ']' == s[i]:
                # 取出字符串要乘的倍数
                mutiple_num = int(char_list[num_list[num_flag]])
                # 取出被乘的字符串
                head = num_list[num_flag] + 1
                tail = char_flag + 1
                str = "".join(char_list[head:tail])
                # 乘好后的字符串
                mutiple_str = mutiple_num * str
                # 将指针倒退回上一个数字位置
                char_flag = num_list[num_flag] - 1
                for data in mutiple_str:
                    char_flag += 1
                    char_list[char_flag] = data
                num_flag -= 1
            i += 1
        final_str = "".join(char_list[0:char_flag + 1])
        return final_str

时间复杂度和空间复杂度

时间: O(n^2) 空间: O(n)

kendj-staff commented 3 years ago
class Solution {
    public String decodeString(String s) {
        //Deque<String> letterStack = new LinkedList<String>();
        //Deque<String> numStack = new LinkedList<Integer>();
        Deque<String> stack = new LinkedList<String>();

        for (int i = 0; i < s.length(); i++) {
            if (']' != s.charAt(i)) {
                stack.push(String.valueOf(s.charAt(i)));
            } else {
                StringBuffer letterSb = new StringBuffer();
                while (Character.isLetter(stack.peek().charAt(0)) && stack.peek().charAt(0) != '[') {
                    letterSb.insert(0,stack.pop());
                }
                stack.pop();

                StringBuffer numSb = new StringBuffer();
                while ( !stack.isEmpty() && Character.isDigit(stack.peek().charAt(0))) {
                    numSb.insert(0,stack.pop());
                }

                int count = Integer.parseInt(numSb.toString());
                StringBuffer sb = new StringBuffer();
                while (count > 0) {
                    sb.append(letterSb.toString());
                    count--;
                }

                stack.push(sb.toString());
            }
        }
        StringBuffer resbuff = new StringBuffer();
        for(String str : stack) {
            resbuff.insert(0,str);
        }
        return resbuff.toString();
    }
}
HondryTravis commented 3 years ago

思路

使用双栈,碰到 [ 数字和当前字符串入栈,碰到 ] 数字和字符串出栈。

代码[js]

var decodeString = function(s) {
    const countStack = [], strStack = []  // 一个放倍数,一个放拼接的
    let num = 0, result = ''

    for (const ch of s) {
        if (!isNaN(ch)) num = num * 10 + Number(ch)
        else if (ch === '[') {
            strStack.push(result)
            result = ''        
            countStack.push(num) 
            num = 0               
        } else if (ch === ']') { 
            const count = countStack.pop()
            result = strStack.pop() + result.repeat(count)
        } else result += ch                  

    }
    return result
};

复杂度分析

时间复杂度: O(n)

空间复杂度: O(n)

iambigchen commented 3 years ago

思路

遍历s, 如果遇到数字和字符串,拼接起来,遇到[ 则把拼接后的数字和字符串存起来,遇到]则把存起来的数字和字符串取出来,用数字倍数拼接字符串

代码

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
    let repeatNum = []
    let repeatStr = []
    let str = ''
    let num = ''
    for (const c of s) {
        if (!isNaN(c)) {
            num += c
        } else if (c ==='[') {
            repeatStr.push(str)
            repeatNum.push(Number(num))
            str = '' 
            num = ''
        } else if (c === ']') {
            str = repeatStr.pop() + str.repeat(repeatNum.pop())
        } else {
            str += c
        }
    }
    return str
};

复杂度

时间复杂度O(n) 空间复杂度O(m+n)

DAXIAdaxia commented 3 years ago

Java


思路

一般遇到括号类的首先应该想到栈

代码

class Solution {

    int p;

    public String decodeString(String s) {
        LinkedList<String> stack = new LinkedList<>();
        p = 0;
        while(p < s.length()){
            char ch = s.charAt(p);
            if(Character.isDigit(ch)){
                stack.addLast(getDigital(s));
            }else if(ch == '[' || Character.isLetter(ch)){
                stack.addLast(String.valueOf(ch));
                p++;
            }else{
                p++;
                LinkedList<String> subStr = new LinkedList<>();
                while(!"[".equals(stack.peekLast())){
                    subStr.add(stack.removeLast());
                }
                Collections.reverse(subStr);
                stack.removeLast();
                int repCount = Integer.parseInt(stack.removeLast());
                String repStr = getString(subStr);

                StringBuffer sb = new StringBuffer();

                while(repCount > 0){
                    sb.append(repStr);
                    repCount--;
                }

                stack.addLast(sb.toString());
            }
        }
        return getString(stack);
    }

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

    public String getString(List<String> list){
        StringBuffer sb = new StringBuffer();
        for(String s : list)
            sb.append(s);
        return sb.toString();
    }
}

复杂度分析:

ZoharZhu commented 3 years ago

思路

类似括号匹配,遍历字符串, 如果是数字,就计算当前数字; 如果是字符,入栈; 如果是左括号,先把当前计算好的数字入栈,再把左括号入栈; 如果是右括号,先把栈顶字符串依次出栈并拼接起来,直到碰到左括号。左括号出栈后,栈顶是重复次数,根据次数展开当前字符串后入栈。 遍历结束后把栈内所有已解码完成的字符串拼接起来。

代码

/**

TC: O(ans.length) SC: O(ans.length)

naomiwufzz commented 3 years ago

思路

不是']'就全部入栈,碰到']'开始解码,解码就是一个个拆出来,碰到'['停止拆字符串,碰到数字就另外算要重复的数字是多少。这里有两个地方容易错,一个是数字未必是个位数,一个是出栈之后的str不要直接拼到结果上,继续入栈(不然这样的case无法通过"3[a2[c]]"),最后把栈当作结果join一下即可。

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for i, char in enumerate(s):
            if char != ']':
                stack.append(char)
            elif char == ']':
                repeat_s = ''
                while stack and stack[-1] != '[':
                    repeat_s = stack.pop() + repeat_s
                stack.pop() # pop 掉'['
                cnt = ''
                while stack and stack[-1].isdigit(): # 可能有多个数字
                    cnt = stack.pop() + cnt
                repeat_s = repeat_s * int(cnt)
                stack.append(repeat_s) # 这里是一个要点,重复的字符串直接压回栈里
        return ''.join(stack)

复杂度分析

agentzzz commented 3 years ago

思路

辅助栈


class Solution {
public:
    string decodeString(string s) {
        int multi = 0;
        stack<int>stk_multi;
        stack<string>stk_res;
        string res = "";
        for(int i =0;i<s.size();i++)
        {
            if(s[i]=='[')
            {
                stk_multi.push(multi);
                stk_res.push(res);
                multi = 0;
                res = "";
            }
            else if(s[i]==']')
            {
                string temp = "";
                int curmulti = stk_multi.top();
                stk_multi.pop();
                for(int i = 0;i<curmulti;i++)
                {
                    temp+=res;
                }
                res = stk_res.top()+temp;
                stk_res.pop();
            }
            else if(isdigit(s[i])) multi = multi*10 + s[i]-'0';
            else res+=s[i];
        }
        return res;
    }
};
NorthSeacoder commented 3 years ago

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function (s) {
    const stack = [];
    for (let char of s) {
        if (char === ']') {
            let repeatRes = '', repeats = '';
            let str = stack.pop();
            while (str !== '[') {
                repeatRes = str + repeatRes;
                str = stack.pop()
            }
            let num = stack.pop()
            while (!isNaN(num)) {
                repeats = num + repeats;
                num = stack.pop()
            }
            stack.push(num);//多弹出的字符串
            repeatRes = repeatRes.repeat(parseInt(repeats));
            stack.push(repeatRes)

        } else {
            stack.push(char)
        }
    }
    return stack.join('')

};
carterrr commented 3 years ago

class 字符串解码_394{     public String decodeString(String s) {         // 遇到[开始把前面一个入栈  以及后面的         Deque cStack = new LinkedList<>();         Deque iStack = new LinkedList<>();

        String res = ""; // 存储本次[] 中的字符串           int num = 0;     //  存储本次[ 前面的倍数         for(char c : s.toCharArray()) {             if(c >= '0' && c <= '9') { // 是数字                 num = num * 10 +  (c - '0'); // 23[ab] 这种  数字是23倍             } else if( c == '[') {  // [ 将之前的字符串和倍数入栈保存                  cStack.push(res);                 iStack.push(num);                 res = "";                 num = 0;             } else if( c == ']' ) { // ] 用数字栈顶数字来倍化 [] 中的元素                 String tmpRes = res;                 final int repeat = iStack.pop() - 1;                 for(int i = 0; i < repeat; i++ ) {                     tmpRes = tmpRes + res;                 }                 res = cStack.pop() + tmpRes; //加上 数字前面的字符串 没有就是 ""             } else {                 res = res + c;             }         }         return  res;     } }

carinSkyrim commented 3 years ago

思路

递归

代码

class Solution(object):
    def decodeString(self, s):
        """
        :type s: str
        :rtype: str
        """
        if not s:
            return ''

        def helper(s, start):
            tmpnum = 0
            index = start
            r = ''
            while index < len(s):
                if ord('0') <= ord(s[index]) <= ord('9'):
                    tmpnum = tmpnum*10 + int(s[index])
                    index += 1
                elif s[index] == '[':
                    tmpr, location = helper(s, index+1)
                    r += tmpnum * tmpr
                    index = location + 1
                    tmpnum = 0
                elif s[index] == ']':
                    return r, index
                else:
                    r += s[index]
                    index += 1
            return r
        return helper(s, 0)

复杂度

时间复杂度 O(n) 空间复杂度 O(n)

sxr000511 commented 3 years ago

题目地址(394. 字符串解码)

https://leetcode-cn.com/problems/decode-string/

题目描述

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[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"

前置知识

公司

思路

关键点

代码

JavaScript Code:


/**
 * @param {string} s
 * @return {string}
 */
const decodeString = (s) => {
    let numStack = [];        // 存倍数的栈
    let strStack = [];        // 存 待拼接的str 的栈
    let num = 0;              // 倍数的“搬运工”
    let result = '';          // 字符串的“搬运工”
    for (const char of s) {   // 逐字符扫描
        if (!isNaN(char)) {   // 遇到数字
            num = num * 10 + Number(char); // 算出倍数
        } else if (char == '[') {  // 遇到 [
            strStack.push(result); // result串入栈
            result = '';           // 入栈后清零
            numStack.push(num);    // 倍数num进入栈等待
            num = 0;               // 入栈后清零
        } else if (char == ']') {  // 遇到 ],两个栈的栈顶出栈
            let repeatTimes = numStack.pop(); // 获取拷贝次数
            result = strStack.pop() + result.repeat(repeatTimes); // 构建子串
        } else {                   
            result += char;        // 遇到字母,追加给result串
        }
    }
    return result;
};
iciue commented 3 years ago

思路

利用栈匹配括号,提取需要重复的元素和需要重复的次数

代码

function decodeString(s: string): string {
  let result = []
  for (let i = 0; i < s.length; i++) {
    const c = s[i]
    if (c === ']') {
      let repeatSt = ''
      let repeatCnt = ''

      while (result[result.length - 1] !== '[') {
        repeatSt = result.pop() + repeatSt
      }

      result.pop()

      while (/\d/.test(result[result.length - 1])) {
        repeatCnt = result.pop() + repeatCnt
      }

      result.push(...repeatSt.repeat(~~repeatCnt));

    } else {
      result.push(c);
    }
  }
  return result.join('');
};

复杂度

时间 O(n) 空间 O(n)

HWFrankFung commented 3 years ago

Ideas

I use two stacks to store the multiples in front of the [ while the other does the same job on the letters called numStack and strStack. When it gets the [, numbers in front of it should be push into the first stack while the letters are pushed into the other. When it meets ], it's time to construct the result with the former elements stored.

Code


var decodeString = function(s) {
    let numStack = [];        
    let strStack = [];        
    let num = 0;              
    let res = '';        
    for (const char of s) {   
        if (!isNaN(char)) {   
            num = num * 10 + Number(char); 
        } else if (char == '[') {  
            strStack.push(res); 
            res = '';           
            numStack.push(num);   
            num = 0;              
        } else if (char == ']') {  
            let Times = numStack.pop(); 
            res = strStack.pop() + res.repeat(Times); 
        } else {                   
            res += char;        
        }
    }
    return res;
};

Complexity

Time: O(n)
Space:O(n)

HZHENGZHI commented 3 years ago

思路 利用栈提取处数字和字母 代码

public String decodeString(String s) {
        Stack<Integer> numstack = new Stack<>();
        Stack<String> strstack = new Stack<>();
        String res = "";
        int num = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
            } else if (c == '[') {
                numstack.push(num);
                strstack.push(res);//将未遇到[之前的字母加入栈,同时也可以防止stack出现空栈出栈异常问题,用来存放上一次解码的数据
                num = 0;
                res = "";//置空后的res用于存储[]内的字符串
            } else if (Character.isLetter(c)) {
                res += c;
            } else if (c == ']') {
                String temp = "";
                int count = numstack.pop();
                for (int j = 0; j < count; j++) {
                    temp = temp + res;
                }
                res = strstack.pop() + temp;//strstack用于存储上次解码后的结果

            }
        }
        return res;
    }

复杂度

guangshisong commented 3 years ago

Day-4:2021-09-13

思路

有思路,写不出,还需要再研究一下

代码

class Solution:
    def decodeString(self, s: str) -> str:

        num_stack = []  
        num_val = 0
        result = ""  
        for ele in s:
            if ele.isdigit():
                num_val = num_val * 10 + int(ele)
            elif ele == "[":
                num_stack.append([result, num_val])
                result, num_val = "", 0
            elif ele == "]":
                top = num_stack.pop()
                result = top[0] + result * top[1]
            else:
                result += ele
        return result
alwaysbest commented 3 years ago

思路

利用栈处理数字、字母、括号

代码


class Solution {
    public String decodeString(String s) {
        Deque<Integer> numStack = new LinkedList<>();
        Deque<String> wordStack = new LinkedList<>();
        StringBuilder curr = new StringBuilder();
        int multi = 0;

        for (char c : s.toCharArray()) {
            if (c <= '9' && c >= '0') {
                multi = multi * 10 + c - '0';
            } else if (c == '[') {
                wordStack.push(curr.toString());
                numStack.push(multi);
                multi = 0;
                curr = new StringBuilder();
            } else if (c == ']') {
                int count = numStack.pop();
                StringBuilder tmp = new StringBuilder(wordStack.pop());
                for (int i = 0; i < count; i++) {
                    tmp.append(curr);
                }
                curr = tmp;
            } else {
                curr.append(c);
            }
        }
        return curr.toString();
    }
}
juleijs commented 3 years ago

思路

利用字符串栈、数字栈和拼接的字符串来接,遍历每一个字符

XinWang20236 commented 3 years ago
class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for c in s:
            if c == ']':
                repeatcount = ''
                repeatstr = ''
                while stack[-1] != '[':
                    repeatstr = stack.pop() + repeatstr
                stack.pop()
                while stack and stack[-1].isnumeric():
                    repeatcount =  stack.pop() + repeatcount
                stack.append(int(repeatcount) * repeatstr)
            else:
                stack.append(c)
        return ''.join(stack)
Richard-LYF commented 3 years ago

class Solution(object): def decodeString(self, s): """ :type s: str :rtype: str """ stack, res, multi = [], "", 0 for c in s: if c == '[': stack.append([multi, res]) res, multi = "", 0 elif c == ']': cur_multi, last_res = stack.pop() res = last_res + cur_multi res elif '0' <= c <= '9': multi = multi 10 + int(c)
else: res += c return res

chenbihao commented 3 years ago

思路

栈、括号匹配

关键点

遇到左括号就进行压栈处理,遇到右括号就弹出栈

性能不太行,晚点优化

代码

Java Code:


    public String decodeString(String s) {

        Stack<Integer> countStack = new Stack();
        Stack<String> StrStack = new Stack();
        String count = "";
        String str = "";

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                // 遇到数字就记录   也可以用这个来判断是否数字:  if (Character.isDigit(c)) {
                count += Integer.parseInt(String.valueOf(c));
            } else if (c == '[') {
                // 遇到左括号就入栈
                countStack.push(Integer.parseInt(count));
                StrStack.push(str);
                count = str = "";
            } else if (c == ']') {
                // 遇到右括号就出栈
                Integer c1 = countStack.pop();
                String temp = "";
                for (int j = 0; j < c1; j++) {
                    temp += str;
                }
                str = StrStack.pop() + temp;
            } else {
                // 记录字母
                str += c;
            }
        }
        return str;
    }

复杂度分析

maqianxiong commented 3 years ago

394. 字符串解码 - 力扣(LeetCode) (leetcode-cn.com)

394

思路

分为四种情况,数字,字母,[ 和 ]时候分别讨论

当为数字时候,可能为连续的数字的情况要考虑到

代码

class Solution {
    public String decodeString(String s) {
        StringBuilder res = new StringBuilder();
        int multi = 0;
        LinkedList<Integer> stackMulti = new LinkedList<>();
        LinkedList<String> stackRes = new LinkedList<>();
        for(Character c :s.toCharArray()){
            if(c >= '0' && c <='9'){
                multi  = multi*10 + Integer.parseInt(c + "");
            }else if(c == '['){
                stackMulti.addLast(multi);
                stackRes.addLast(res.toString());
                res = new StringBuilder();
                multi = 0;
            }else if(c == ']'){
                StringBuilder tmp = new StringBuilder();
                int curMulti = stackMulti.removeLast();
                for(int i = 0; i < curMulti; i++){
                    tmp.append(res);
                } 
                res = new StringBuilder(stackRes.removeLast() + tmp);
            }else{
                res.append(c);
            }

        }
        return res.toString();
    }
}

复杂度分析

MissNanLan commented 3 years ago

思路

1、 遍历 s 字符串,假设当前字符为 c 2、 如果是字母的话,拼接字符 curStr = curStr + c 3、 如果是数字的话,放入到一个临时变量 curNum 4、 如果碰到"[",则将 curStr、curNum 入栈 stack,入栈之后 curStr、curNum 设为初始值 5、 如果碰到"]", 则依次出栈,分别记作 prevStr、prevNum 6、出栈的时候,拼接字符串 curStr = prevStr + curStr.repeat(prevNum);

思考: stack 里面相邻的一定是字母数字隔开的吗,有没有可能出现连续的字母或数字

代码

JavaScript Code:


/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {

  var curStr = "",
    curNum = 0,
    stack = [];
  for (var i = 0; i < s.length; i++) {
    var c = s.charAt(i);
    if (c >= "0" && c <= "9") {
      curNum = curNum * 10 + Number(c);
    } else if (c === "[") {
      stack.push(curNum);
      stack.push(curStr);
      curStr = "";
      curNum = 0;
    } else if (c === "]") {
      let prevStr = stack.pop();
      let prevNum = stack.pop();
      curStr = prevStr + curStr.repeat(prevNum);
    } else {
      curStr += c;
    }
  }
  return curStr
};

复杂度分析

令 n 为数组长度。

hewenyi666 commented 3 years ago

题目名称

394. 字符串解码

题目链接

https://leetcode-cn.com/problems/decode-string/

题目思路

遍历字符串,遇到非']'就入栈, 遇到就 '[' 就出栈

code for Python3

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for c in s:
            if c == ']':
                repeatStr = ''
                repeatCount = ''
                while stack and stack[-1] != '[':
                    repeatStr = stack.pop() + repeatStr
                # pop 掉 "["
                stack.pop()
                while stack and stack[-1].isnumeric():
                    repeatCount = stack.pop() + repeatCount
                stack.append(repeatStr * int(repeatCount))
            else:
                stack.append(c)
        return "".join(stack)

复杂度分析