# 394. Decode String

![](https://4272748102-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LekNH5IywF8mjBxFcnu%2Fuploads%2FENnCKekpArVmhuGVPKaq%2F%E5%9C%96%E7%89%87.png?alt=media\&token=09f3552c-bdb0-40ab-9db5-b103d6fbd6b8)



![](https://4272748102-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LekNH5IywF8mjBxFcnu%2Fuploads%2F5xysLhllHBmEVi1H60h1%2F%E5%9C%96%E7%89%87.png?alt=media\&token=642fb54f-65a3-4b45-a7a4-f2a2d812d1d5)



## two stack

```
time: O(n)
space: O(s1+s2), stack space
```

use this

```java
class Solution {
    public String decodeString(String s) {
        Deque<String> strStack = new ArrayDeque<>();
        Deque<Integer> numStack = new ArrayDeque<>();
        StringBuilder cur = new StringBuilder();
        
        for (int i = 0; i < s.length(); i++) {
            if (Character.isDigit(s.charAt(i))) {
                int i0 = i;
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    i++;
                }
                int num = Integer.valueOf(s.substring(i0, i));
                numStack.push(num);
                strStack.push(cur.toString());
                cur = new StringBuilder();
                
            } else if (s.charAt(i) == ']') {
                
                int repeat = numStack.pop();
                String temp = cur.toString();
                for (int j = 0; j < repeat-1; j++) {
                    cur.append(temp);
                }
                cur = new StringBuilder(strStack.pop() + cur);
                
            } else if (Character.isLetter(s.charAt(i))) {
                cur.append(s.charAt(i));
            }
        }
        return cur.toString();
    }
}

/*
number: add number to number, cur str stack
1. number add to num stack, 因為 num 後面就是 [, so add cur to str stack too, clear cur
2. char: add to cur
3. 遇到 ], num 出戰, str 出站, num*str => set to cur 

     aaa 
3    ""
num. str

cur aaa -> ""

     
2    
num. str

cur aaabcbc => ans
*/
```







```java
/*
"3[a2[c]]"

countStack: 3  ⇒ 2

resStack: "" ⇒ a

res ""  ⇒ a ⇒ "" c

meets ]

sb(a) + cc ⇒ res = acc

meets ]

countStack: 3

resStack: ""

res acc

sb("") + 3*acc

res = accaccacc

1. number ⇒ push countStack ⇒ number push

 2. '[' ⇒ push resStack ⇒ when '[', push res into it

1. char: add char 

1. ']' ⇒ pop

time: O(n)
space: O(s1+s2), stack space
*/
class Solution {
    public String decodeString(String s) {
        Deque<String> resStack = new ArrayDeque<>();
        Deque<Integer> numStack = new ArrayDeque<>();
        int i = 0;
        StringBuilder res = new StringBuilder();
        while (i < s.length()) {
            if (Character.isDigit(s.charAt(i))) {
                int num = 0;
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    num = num*10 + (s.charAt(i) - '0');
                    i++; // 最後會到下一位, 也就是多加了一次
                }
                numStack.push(num);
                i--; // 外層有個i++, 所這要 i--
            } else if (s.charAt(i) == '[') {
                resStack.push(res.toString());
                res = new StringBuilder();
                
            } else if (s.charAt(i) == ']') {
                StringBuilder temp = new StringBuilder(resStack.pop());
                int times = numStack.pop();
                for (int j = 0; j < times; j++) {
                    temp.append(res);
                }
                res = temp;
            } else {
                res.append(s.charAt(i));
            }
            i++;
        }
        return res.toString();
    }
}




/*
2 stack

d3[a]2[bc]d



3
numStack



when [, push to resStack
resstack



res+=letter


res = d

3
numStack

[

res = ""

d         3 
resstack  numStack


res = "a"

d         3 
resstack  numStack

]
res = "a"

d         3 
resstack  numStack


d3[a]2[bc]d

res = bc
daaa          2
resstack  numStack

res = daaabcbcd


*/
```



## one stack

```java
class Solution {
    public String decodeString(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ']') {
                
                List<Character> list = new ArrayList<>();
                while (stack.peek() != '[') {
                    list.add(stack.pop());
                }
                stack.pop(); // [
                int base = 1;
                int k = 0;
                while (!stack.isEmpty() && Character.isDigit(stack.peek())) {
                    k += (stack.pop() - '0')*base;
                    base *= 10;
                }
                while (k != 0) {
                    for (int j = list.size()-1; j >= 0; j--) {
                        stack.push(list.get(j));
                    }
                    k--;
                }
                
            } else {
                stack.push(s.charAt(i));
            }
        }
        StringBuilder res = new StringBuilder();
        while(!stack.isEmpty()) {
            res.append(stack.pop());
        }
        return res.reverse().toString();
    }
}

/*
3[a2[c]]

c
[
2
a
[
3
*/
```



## recursion

T: O(k\*n), k is call dfs times, n is String length

S: O(n)

```java
class Solution {

    public String decodeString(String s) {
        return dfs(s, 0)[0];
    }
    private String[] dfs(String s, int i) {
        StringBuilder res = new StringBuilder();
        
        int num = 0;
        while(i < s.length()) {
            if(Character.isDigit(s.charAt(i))) { 
                num = num * 10 + (s.charAt(i) - '0'); 
            } else if(s.charAt(i) == '[') { // when [, call dfs(s, i+1) get str in [ str ]
                
                String[] tmp = dfs(s, i + 1);
                i = Integer.parseInt(tmp[0]);
                
                for (int j = 0; j < num; j++) { // multi str, num needs set back to 0
                    res.append(tmp[1]);
                }
                num = 0;
            } else if(s.charAt(i) == ']') { // when end, return String
                return new String[] { String.valueOf(i), res.toString() };
                
            } else { // letter, add
                res.append(s.charAt(i));
            }
            i++;
        }
        return new String[] { res.toString() };
    }
}

/*
d3[a2[c]]d
    /
   a2[c]
   /
   c
   
   so when back, we can deal with number and decoded String
    => 2c => cc
    => acc
    => 3acc
    => daccaccaccd
*/
```



or i as global variable

```java
class Solution {
    int i = 0;
    public String decodeString(String s) {
        return dfs(s);
    }
    private String dfs(String s) {
        StringBuilder res = new StringBuilder();
        
        int num = 0;
        while(i < s.length()) {
            if(Character.isDigit(s.charAt(i))) { 
                num = num * 10 + (s.charAt(i) - '0'); 
            } else if(s.charAt(i) == '[') { // when [, call dfs(s, i+1) get str in [ str ]
                i++;
                String tmp = dfs(s);                
                for (int j = 0; j < num; j++) { // multi str, num needs set back to 0
                    res.append(tmp);
                }
                num = 0;
            } else if(s.charAt(i) == ']') { // when end, return String
                return res.toString();
                
            } else { // letter, add
                res.append(s.charAt(i));
            }
            i++;
        }
        return res.toString();
    }
}
```
