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"

BlueRui commented 3 years ago

Problem 394. Decode String

Algorithm

Complexity

Time Complexity: O(N) where N is the length of the decoded string. Space Complexity: O(N) where N is the length of the decoded string.

Code

Language: Java

public String decodeString(String s) {
   Deque<Character> stack = new ArrayDeque<>();
   for (char c : s.toCharArray()) {
       if (c != ']') {
           stack.addFirst(c);
           continue;
       }
       List<Character> decodedStr = new ArrayList<>();
       while (stack.peekFirst() != '[') {
           decodedStr.add(stack.removeFirst());
       }
       // Remove '['
       stack.removeFirst();

       // Get multiplier
       int num = 0;
       int base = 1;
       // Important to check if stack is empty first
       while (!stack.isEmpty() && Character.isDigit(stack.peekFirst())) {
           // It is very important to keep track of base, as the lower digits may be 0s like "100"
           // Simply using num = num * 10 + stack.removeFirst() - '0' won't work.
           num = num + (stack.removeFirst() - '0') * base;
           base *= 10;
       }

       // Put decoded string back to stack
       for (int i = 0; i < num; i++) {
           for (int j = decodedStr.size() - 1; j >= 0; j--) {
               stack.addFirst(decodedStr.get(j));
           }
       } 
   }
   char[] result = new char[stack.size()];
   for (int i = stack.size() - 1; i >= 0; i--) {
       result[i] = stack.removeFirst();
   }
   return new String(result);        
}
laofuWF commented 3 years ago

💻Code:

# use stack to store a pair number of times + the string to repeat
# use currCount to store how many times to repeat current substring
# use currString to store current string iterated so far

class Solution:
    def decodeString(self, s: str) -> str:
        currString = ''
        currCount = 0
        stack = []

        for char in s:
            if char.isdigit():
                currCount = currCount * 10 + int(char)
            elif char == '[':
                # start of a new subtring
                # store currCount and string
                # reset currCount and string

                stack.append(currString)
                stack.append(currCount)
                currString = ''
                currCount = 0
            elif char == ']':
                # end of this substring
                # pop stack top string pair and add to current String

                count = stack.pop()
                string = stack.pop()
                currString = string +  count * currString
            else:
                currString += char

        return currString
Bingbinxu commented 3 years ago

思路 遇到数字执行10进制的数字计算,前一个比后一个多10倍 遇到[进行压栈处理 遇到]进行出站处理 遇到普通字符,加上就行 代码

class Solution {
public:
    string decodeString(string s) {
        int num = 0;
        string str = "";
        string res = "";
        stack<int> numstack;
        stack<string> strstack;
        int len = s.size();
        for(int i = 0;i < len; i++)
        {
            if(s[i]>='0' && s[i]<='9')
            {
                num = 10*num + s[i] -'0';
            }
            else if(s[i]=='[')
            {
                numstack.push(num);
                strstack.push(str);
                num = 0;
                str = "";
            }
            else if(s[i]==']')
            {
                int j = numstack.top();
                numstack.pop();
                for(int k = 0;k < j;k++ )
                {
                    strstack.top() += str;
                }
                str = strstack.top();
                strstack.pop();
            }
            else
            {
                str +=s[i];
            }

        }
        return str;

    }
};

复杂度 时间复杂度遍历s,同时遍历里面重复[]的次数,复杂度为O(NUM的和) 空间复杂度O([]里的lenth*num)

itsjacob commented 3 years ago

Intuition

Pairing brackets in a string is often associated with stack ADT. We do nothing but pushing each char onto a stack until we encounter the right bracket ']'. When ']' is found, we need to pop elements on the stack until we find its first pairing bracket '['. Then some operations need to be done with the popped elements, in this case, we record the chars in between '[' and ']', and use the knowledge of numeric number right before '[' to repeat the recorded chars. After the operation is done, we can remove the pairing bracket '[' and the numeric number from the stack and push the after-processing chars back to the stack. After iterating through the original string, the stack will be left of pure chars without numeric numbers and brackets. The final results is done backward iterating through the stack.

The key point in implementing it in c++ is that the stack is of type char not string, because char comparison is cheaper than the string comparison.

One caveat when we get the numeric number from the stack is that we need an additional stack to store the digits. This is because we store the number from high digit to low digit, for example, if we have 300[a], the stack is ['3', '0', '0', '[', 'a'], we need to have a helper stack to store the digits ['0', '0', '3']. An optimization can be done by observing that all integers are in the range [1, 300]. We can allocate a static array of size 3 and reset it to ['*', '*', '*'] before we compute the numeric number and fill the digits backwards into the array.

This is a more natural solution to me and sounds like DFS. The two stacks approach consisting of numeric number stack and string stack is kind of hard to memorize for me.

Implementation

class Solution
{
public:
  string decodeString(string s)
  {
    std::stack<char> resStack;
    std::vector<char> digitVec(3, '*');
    for (auto const& c : s) {
      if (c != ']') {
        resStack.push(c);
      } else {
        // Find the chars to be repeated in between '[' and ']'
        std::vector<char> repeatStrVec;
        while (resStack.top() != '[') {
          repeatStrVec.push_back(resStack.top());
          resStack.pop();
        }
        // Remove the '[' from the stack
        resStack.pop();
        // Find the repeat count, and remove the numbers from the stack
        std::fill(digitVec.begin(), digitVec.end(), '*');
        int idx = digitVec.size();
        // static_cast is needed as isdigit has undefined behavior for char type
        while (!resStack.empty() && std::isdigit(static_cast<unsigned char>(resStack.top()))) {
          digitVec[--idx] = resStack.top();
          resStack.pop();
        }
        int count{digitVec[idx] - '0'}; 
        for (int ii = idx+1; ii < digitVec.size(); ii++) {
          count = 10 * count + digitVec[ii] - '0';
        }
        // Repeat the chars in betwen '[' and ']' count times and push them back to the stack
        for (int ii = 0; ii < count; ii++) {
          for (auto it = repeatStrVec.rbegin(); it != repeatStrVec.rend(); it++) {
            resStack.push(*it);
          }
        }
      }
    }
    // Pre-allocate the string so that we don't need string concatenation
    std::string res(resStack.size(), '*');
    int idx = resStack.size();
    while (!resStack.empty()) {
      res[--idx] = resStack.top();
      resStack.pop();
    }
    return res;
  }
};

Complexity

wangyifan2018 commented 3 years ago
import (
    "fmt"
    "strconv"
    "strings"
)

func decodeString(s string) string {
    stk := []string{}
    ptr := 0
    for ptr < len(s) {
        cur := s[ptr]
        if cur >= '0' && cur <= '9'{
            digits := getDigis(s, &ptr)
            stk = append(stk, digits)
        } else if (cur >= 'a' && cur <= 'z' || cur >= 'A' && cur <='Z' || cur =='['){
            stk = append(stk, string(cur))
            ptr++
        } else {
            ptr ++
            sub := []string{}
            for stk[len(stk) - 1] != "[" {
                sub = append(sub, stk[len(stk) - 1])
                stk = stk[:len(stk)-1]
            }
            for i := 0; i < len(sub)/2; i++{
                sub[i], sub[len(sub) -i - 1] = sub[len(sub) -i -1], sub[i]
            }
            stk = stk[:len(stk) - 1]
            repTime, _ := strconv.Atoi(stk[len(stk) -1])
            stk = stk[: len(stk) - 1]
            t := strings.Repeat(getString(sub), repTime)
            stk = append(stk, t)
        }
    }
    return getString(stk)
}

func getDigis(s string, ptr *int) string {
    ret := ""
    for ; s[*ptr] >= '0' && s[*ptr] <= '9'; *ptr++{
        ret += string(s[*ptr])
    }
    return ret
}

func getString(v []string) string {
    ret := ""
    for _, s := range v {
        ret += s
    }
    return ret
}
q815101630 commented 3 years ago

Thought

这道题因为有“[”“]”, 所以我第一时间想到的是用stack(LIFO)。 我们能遍历整个字符串来看如何处理每个字符

  1. 如果当前字符为任意数字,我们便能添加当前数字进入一个叫count的字符串内
  2. 如果当前字符为任意字母,我们便能添加当前字母进入以及个叫ans的字符串内
  3. 如果当前字符为"[",我们便需要把当前countans入栈,这里入栈是因为ans代表了当前'['外层我们想要的字符串,count则表示[内层需要重复的次数。入栈后当前anscount清空
  4. 如果当前字符为"]", 我们则出栈得到"[" 之前的原ans+重复次数,让ans更新为原ans+重复次数*ans

Python

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        ans = ""
        count = ""

        for char in s:
            if "0" <= char <= "9":
                count += char
            elif "a" <= char <= "z":
                ans += char
            elif char == "]":
                pair = stack.pop()
                ans = pair[1]+ int(pair[0])*ans
                #count = ""
            elif char == "[":
                stack.append((count, ans))
                count = ""
                ans = ""
        return ans

Time Complexity: O(n) 遍历整个字符串 Space complexity: O(n) 最多有可能创建一个 n 长度的stack

xj-yan commented 3 years ago

Code

class Solution {
    public String decodeString(String s) {
        Stack<String> stack = new Stack<>();
        Stack<Integer> numStack = new Stack<>();

        StringBuilder res = new StringBuilder();
        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);
                num = 0;
                stack.push(res.toString());
                res = new StringBuilder();
            }else if(c == ']'){
                StringBuilder tmp = new StringBuilder(stack.pop());
                int rep = numStack.pop();
                for (int k = 0; k < rep; k++){
                    tmp.append(res);
                }
                res = tmp;
            }else {
                res.append(c);
            }
        }
        return res.toString();
    }
}

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

Joyce94 commented 3 years ago
思路

两个栈,一个字母栈,一个数字栈 左括号开始就进入字母栈,右括号就开始出栈(出栈生成的结果要重新入字母栈),括号也要进栈,标志边界

a:3 2 -> a:3 -> a:

    # b:[ a [ c ]    -> b:[ a c c ] -> b:a c c a c c a c c
    # res: a c c a c c a c c
    # a:3       -> a:2              -> a:
    # b:[ a ]   -> b:a a a [ b c ]  -> b:a a a b c b c 
    # res:
代码
class Solution:
    def decodeString(self, s: str) -> str:
        '''
        case: "100[leetcode]"
        '''
        stack_num = []
        stack_alpha = []
        flag = False 
        for i in range(len(s)):
            cur = s[i]
            if cur.isdigit():
                if flag is False:
                    stack_num.append(int(cur))
                else:
                    pre = int(stack_num.pop())
                    num = pre * 10 + int(cur) 
                    stack_num.append(num)
                flag = True
            elif cur == ']':
                flag = False
                word = ''
                while len(stack_alpha) > 0:
                    tmp = stack_alpha.pop()
                    if tmp == '[':
                        break
                    word += tmp
                # 逆序退出栈
                count = int(stack_num.pop())
                while count > 0:
                    # for ele in word:
                    for j in range(len(word) - 1, -1, -1):
                        stack_alpha.append(word[j])
                    count -= 1 
            else:
                flag = False
                stack_alpha.append(cur)
        if len(stack_num) != 0:
            return ''    
        return ''.join(stack_alpha)
复杂度

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

shamworld commented 3 years ago

思路

通过两个数组维护数字栈和字符串栈

代码

var decodeString = function (s) {
    let numList = [];//存放数字
    let numStr = '';//存放数字长度
    let stackList = [];//存放字符串
    let str = '';//存放括号里面的字符串
    let result = '';//返回值
    for (let i = 0; i < s.length; i++) {
        const n = s.charAt(i);
        if (n >= 0 && n <= 9) {
            numStr += n;
        } else if (n === '[') {//这时说明前面数字,字符串已经匹配完了
            numList.push(numStr);
            stackList.push(str);
            numStr = '';
            str = '';
        } else if (n === ']') {
            const num = numList.pop();
            let t = '';
            for (let j = 0; j < num; j++) {
                t += str;
            }
            //已经计算了一个闭环,就要判断stackList中还存不存在字符串,存在就加,例如:3[a2[c]]=>3[acc]
            let temp = stackList.length > 0 ? stackList.pop() : '';
            str = temp + t;
            //如果当前数字数组中没有数据了,那就说明当前位置已经没有可以重复的字符串了,直接加入到返回值里面
            if (numList.length === 0) {
                result += str;
                str = '';
            }
        } else {
            //如果当前数字数组中没有数据了,那就说明当前位置已经没有可以重复的字符串了,直接加入到返回值里面
            if (numList.length === 0) {
                result += n;
            } else {
                str += n;
            }
        }
    }

    return result;
};
akxuan commented 3 years ago

这题看着容易, 但是实现好不容易。

思路

首先弄两个 stack, 其中一个存数字, 另一个存string。 然后每次遇到 ']' 的时候就把string 中最后一个替换成 数字stack[-1]* str_stack[-1].

  1. 首先就是需不需要用一个string 来存output。 如果用一个res 存output, 那就还要再判断一次 num_stack 是不是空的, 这个就蛋疼了。
  2. 最后用 ''.join(stack) 返回非常好。 因为就算有空 string 也不影响
class Solution:
    def decodeString(self, s):
        stack_num, stack_string =  [],[""]
        num = 0
        res = ''
        for c in s:
            if  c.isdigit():
                num = num*10 + int(c)
            elif c =='[':
                stack_string.append("")
                stack_num.append(num)
                num = 0 
            elif c == ']':
                temp_str = stack_string.pop()
                temp_rep = stack_num.pop()
                last_str = stack_string.pop()
                stack_string.append(last_str+ temp_rep*temp_str)
            else:
                stack_string[-1] += c
        return "".join(stack_string)
Cartie-ZhouMo commented 3 years ago

思路

遇到'['时,栈内保存当前子串和倍数。遇到']'时,弹出栈顶并与当前子串组合。

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        ans = ''
        num = 0
        for c in s:
            if '0' <= c <= '9':
                # 注意数字位数
                num = num*10 + int(c)
            elif c == '[':
                stack.append((num, ans))
                ans = ''
                num = 0
            elif c == ']':
                cnt, tmp_str = stack.pop()
                ans = tmp_str + ans*cnt
            else:
                ans += c
        return ans

复杂度

TimmmYang commented 3 years ago

思路

结果需要从括号内向外逐层解开,使用栈可以达到我们的目标。最后在栈内的字符串都是解好的字符串,连起来返回即可。

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for c in s:
            if c == ']':
                mul = ''
                tmp = ''
                while stack and stack[-1] != '[':
                    tmp = stack.pop() + tmp. # 在前面pop后面就不用翻转了
                stack.pop()
                while stack and stack[-1].isdigit():
                    mul = stack.pop() + mul
                tmp = tmp * int(mul)
                stack.append(tmp)
            else:
                stack.append(c)
        return ''.join(stack)

复杂度

时间:O(N),N为s长度 空间:O(N)

ysy0707 commented 3 years ago
class Solution {
    //c为数字:转化为数字num
    //c为字母:在res尾部添加c
    //c为‘[’:将当前num和res入栈stack,并将两者分别空置
    //c为‘]’:stack出栈,res = 刚出栈的res + 当前res * 刚出栈的数字num

    public String decodeString(String s) {
        StringBuilder res = new StringBuilder();
        int num = 0;

        LinkedList<Integer> stackNum = new LinkedList<>();
        LinkedList<StringBuilder> stackRes = new LinkedList<>();

        for(Character c : s.toCharArray()){
            if(c >= '0' && c <= '9'){
                num = num * 10 + c - '0';
            }else if(c == '['){
                stackNum.addLast(num);
                stackRes.addLast(res);
                num = 0;
                res = new StringBuilder();
            }else if(c == ']'){
                int curNum = stackNum.removeLast();
                StringBuilder tmp = new StringBuilder();
                for(int i = 0; i < curNum; i++){
                    tmp.append(res);
                }
                res = stackRes.removeLast();
                res.append(tmp);
            }else{
                res.append(c);
            }
        }
        return res.toString();
    }
}

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

ZhuMengCheng commented 3 years ago

思路两个栈存储倍数和需要翻倍的字符.判断[]位置翻倍存储当前字符..翻倍所有字符后拼接返回完整字符

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function (s) {
    let num = 0;
    let numStock = []
    let resultStock = []
    let result = ''
    for (let str in s) {
        if (!isNaN(s[str])) {
            num = num * 10 + Number(s[str])
        } else if (s[str] == '[') {
            resultStock.push(result);
            result = '';
            numStock.push(num)
            num = 0;
        } else if (s[str] == ']') {
            let copyNum = numStock.pop();
            result = resultStock.pop() + result.repeat(copyNum);
        } else {
            result += s[str]
        }
    }
    return result
};
console.log(decodeString('3[a]2[bc]'))

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

minuet-red commented 3 years ago

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

class Solution {
public:
    string decodeString(string s) {
        string res;   // 字符串形式的栈
        for (int i = 0; i < s.size(); i++) {    // 遍历整个string
            if (s[i] != ']') {
                res += s[i];
            }
            else if (s[i] == ']') {                  // 如果到']'就往回走
                string saveStr = "";            // 每次循环初始化
                string saveNum = "";
                while (res.back() != '[') {   // 前面一定有'['
                    saveStr = res.back() + saveStr;   // 记录括号内的字符串
                    res.pop_back();           // 往前走
                }
                res.pop_back();               // 去掉'['
                while (res.size() != 0 && isdigit(res.back())) {   // 前面是数字且不越界都成立才循环
                    saveNum = res.back() + saveNum;          // 记录前面的数字
                    res.pop_back();           // 往前走
                } // 得到数字和数字作用的字符串,已解出当前括号
                int n = stoi(saveNum);
                while (n--) {
                    res += saveStr;
                }
            }
        }

        return res;
    }
};
james20141606 commented 3 years ago

Day 4 394. Decode String

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

题目

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

思路

该问题需要由内向外扩展,很明显可以用到stack先进后出的特性。 具体到问题上来,我们新创建额外两个stack,一个用来存数字,一个用来存字母。当遇到数字时,将数字记录下来为multi(要记得处理连续数字的情况);当遇到字母时,直接append到res;当遇到'[\' 符号时,将当前的res和multi压入各自的stack中,并且将multi和res初始化;当遇到']\'时,需要初始化一个tmp变量,pop出multi里的数字,并迭代加入res到tmp中去,最后要将结果初始为tmp + res.pop()。

代码

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

复杂度分析

时间复杂度

O(n)

空间复杂度

O(n)

15691894985 commented 3 years ago

9.13 day3 394.字符串解码

思路:

复杂度分析:

watermelonDrip commented 3 years ago
class Solution:
    def decodeString(self, s: str) -> str:
        stack =[]
        res = ''
        k = 0
        for elem in s:
            if '0' <=  elem  <= '9':
                k  = k*10+ int(elem)
            elif elem == '[':
                stack.append([res, k])
                res = ''
                k =0

            elif elem == ']':
                tmp_str, tmp_k = stack.pop()

                res = tmp_str + res * tmp_k 

            else:
                res =  res + elem 

        return res
     time:O(N)        
space(O(N))
WeilanTao commented 3 years ago

394 Decode String Medium

Idea

In this question, the encoded string is composed by two parts: string cascading and sub-string in the brackets.

Code

class Solution {  
    public String decodeString(String s) {
        StringBuilder sb  = new StringBuilder();
        int len = s.length();

        int i = 0;
        while(i < len){
            char c = s.charAt(i);
            if(c-'a' >= 0 && c-'z' <= 0){
                sb.append(c);
                i++;
            }else if(c-'0' >= 0 && c -'9' <= 0){
                //find the first open bracket
                int strt =  s.indexOf("[",i);
                int end = findEnd(strt, len, s);
                String mids= s.substring(strt+1, end);
                String subs = decodeString(mids);

                //find the number
                String numstr = s.substring(i,strt);
                int num = Integer.parseInt(numstr);

                for(int j = 0; j < num ;j++){
                    sb.append(subs);
                }
                i = end+1;
            }
        }

        return sb.toString();
    }

    private int findEnd(int strt, int len, String s){
        Deque<Character> brkt = new ArrayDeque<>();
        brkt.push(s.charAt(strt));
        for(int i = strt+1; i <= len ; i++){
            char c = s.charAt(i);
            if(c == '[')
                brkt.push(c);
            else if( c == ']')
                brkt.pop();

            if(brkt.peek() == null)
                return i;
        }
        return -1;
    }
}

Runtime: 0 ms, faster than 100.00% of Java online submissions for Decode String.

Memory Usage: 36.9 MB, less than 84.66% of Java online submissions for Decode String.

Complexity

Time: O(N)

Space: O(N) for the stack

st2yang commented 3 years ago

思路

代码

复杂度

zhousibao commented 3 years ago

ts

function decodeString(s: string): string {
    const stack = []
    let str = ''
    let num = ''
    for(const i of s){
        if(!isNaN(+i)){
            num += i
        } else if( i === '['){
            stack.push(+num)
            num = ''
            stack.push(i)
        } else if( i === ']'){
            str = ''
            while( stack[stack.length - 1] !== '['){
                // 注意顺序
                str = stack.pop() + str
            }
            // stack[stack.length - 1] === '['
            stack.pop()
            stack.push(str.repeat(stack.pop()))
        } else {
            stack.push(i)
        }
    }
    return stack.join('');
};
chun1hao commented 3 years ago
var decodeString = function (s) {
  let strStack = [];
  let numStrack = [];
  let tempNum = 0;
  for (let i of s) {
    if (!isNaN(i)) {
      tempNum = tempNum * 10 + +i;
    } else if (i === "]") {
      let str = "";
      let cur = strStack.pop();
      let repeat = numStrack.pop();
      while (cur && cur !== "[") {
        str = cur + str;
        cur = strStack.pop();
      }
      str = str.repeat(repeat);
      strStack.push(str);
    } else {
      strStack.push(i);
      if (tempNum) {
        numStrack.push(tempNum);
        tempNum = 0;
      }
    }
  }
  return strStack.join("");
};

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

JK1452470209 commented 3 years ago

思路

使用字符栈与数字栈,遇到 [ 就进栈 遇到 ] 就出栈,出栈时将字符栈,数字栈同时出栈并运算。还需要考虑数字的进位问题 ret变量缓存着从栈底弹出字符串总和,并且有将字符串压入栈底的作用

代码

class Solution {
    public String decodeString(String s) {
        Stack<String> stacks = new Stack<>();
        Stack<Integer> nums = new Stack<>();
        String ret = "";
        int num = 0;
        for (char c : s.toCharArray()){
            if ('0' <= c && c <= '9'){
                num=num*10+c-'0';
            }else if('a' <= c && c <= 'z'){
                ret += c;
            }else if (c == '['){
                stacks.push(ret);
                nums.push(num);
                ret = "";
                num = 0;
            }else {
                Integer cur = nums.pop();
                String stackTemp = stacks.pop();
                for (int i = 0; i < cur; i++) {
                    stackTemp += ret;
                }
                ret = stackTemp;
            }
        }
        return ret;
    }
}

复杂度

时间复杂度:O(N)

空间复杂度:O(N)

JinhMa commented 3 years ago

class Solution { public String decodeString(String s) { char[] c = s.toCharArray(); int l = c.length; Stack num = new Stack<>(); Stack record = new Stack<>(); int start = 0; while (start<l){ if (Character.isDigit(c[start])){ int shu = 0; while (Character.isDigit(c[start])){ shu = shu * 10 + c[start]-'0'; start++; } start--; num.add(shu); } else if (c[start]==']'){ int tmp = num.peek(); num.pop(); String str = ""; StringBuilder sb = new StringBuilder(); while(!record.peek().equals("[")){ sb = sb.append(record.peek()); record.pop(); } if (record.peek().equals("[")){ record.pop(); } for (int i=0;i<tmp;i++){ str = str + sb; } record.add(str); } else { record.add(String.valueOf(c[start])); } start++; } StringBuilder ans = new StringBuilder(); while (!record.isEmpty()){ ans = ans.append(record.peek()); record.pop(); } return ans.reverse().toString(); } }

shixinlovey1314 commented 3 years ago

Title:394. Decode String

Question Reference LeetCode

Solution

Naturally, we can think of using stack to solve this problem, we start push to then stack when we see a digit and start pop the stack when we see the ']', untill we see the '[' at that point we save all the chars between '[' and ']' into a temp string, we then popup the digit from the stack and add them into the result. the only issue is when the encoded string itself is enbeded with another encoded string. To solve this, we can so a small modification to the stack, after we decode the string using the stack, we check if the stack is NULL,

Code

class Solution {
public:
    string decodeString(string s) {
        string result;
        stack<char> encodingStack;
        bool isPush = false;

        for (char c : s) {
            if (isdigit(c) || (isPush && c != ']')) {
                isPush = true;
                encodingStack.push(c);
            } else if (c == ']') {
                isPush = false;

                string tmp;
                while (!encodingStack.empty() && encodingStack.top() != '[') {
                    tmp.push_back(encodingStack.top());
                    encodingStack.pop();
                }
                // pop out '['
                encodingStack.pop();
                reverse(tmp.begin(), tmp.end());

                string numStr;

                while (!encodingStack.empty() && isdigit(encodingStack.top())) {
                    numStr.push_back(encodingStack.top());
                    encodingStack.pop();
                }

                reverse(numStr.begin(), numStr.end());             

                // pop out num
                int num = stoi(numStr);

                string addition;
                for (int i = 0; i < num; i++) {
                    addition.append(tmp);
                }

                if (encodingStack.empty())
                    result.append(addition);
                else {
                    for (char ch : addition)
                        encodingStack.push(ch);
                    isPush = true;
                }

            } else {
                result.push_back(c);
            }
        }

        return result;
    }
};

Complexity

Time Complexity and Explaination

O((maxK to the power of countK)* n): countK is the maximum nested level and maxK is the maximum value of K.

Space Complexity and Explaination

O((maxK to the power of countK)* n)

bolunzhang2021 commented 3 years ago

JAVA 栈

import java.util.*;
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()) {
            if (Character.isDigit(s.charAt(idx))) {
                int count = 0;
                while (Character.isDigit(s.charAt(idx))) {
                    count = 10 * count + (s.charAt(idx) - '0');
                    idx++;
                }
                countStack.push(count);
            }
            else if (s.charAt(idx) == '[') {
                resStack.push(res);
                res = "";
                idx++;
            }
            else if (s.charAt(idx) == ']') {
                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;
    }
}

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

doMoreCode commented 3 years ago

思路

想法是使用栈来进行字符串的复制工作,但是我参考了leetcode的官方的思路,使用了两个栈,一个栈是用来存储数字,另一个用来存储字符串。

AgathaWang commented 3 years ago

迭代法

# python
class Solution(object):
    def decodeString(self, s):
        """
        :type s: str
        :rtype: str
        """
        stack = []
        for w in s:
            repeat_ct = ""
            repeat_char = ""
            if w == "]":
                while stack[-1] != '[':
                    repeat_char = stack.pop() + repeat_char
                stack.pop() # delete [
                while stack and stack[-1].isnumeric():
                    repeat_ct = stack.pop() + repeat_ct
                temp = int(repeat_ct)*repeat_char
                stack.append(temp)
            else:
                stack.append(w)
        return "".join(stack)

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

AruSeito commented 3 years ago

思路

遇到非]进栈,遇到]就出栈,遇到[前将出栈的拼成一个字符串,然后[之前的所有数字都出栈拼成重复次数,按照重复次数重复前面拼成的字符串,拼成的结果再放到栈里去,最终结果就是栈里的各个项拼成的字符串

var decodeString = function (s) {
  const stack = [];
  for (let i = 0; i < s.length; i++) {
    switch (s[i]) {
      case "]": {
        let str = "";
        while (stack[stack.length - 1] !== "[") {
          str = stack.pop() + str;
        }
        stack.pop();
        let number = 0,
          count = 0;
        while (stack[stack.length - 1] >= 0 && stack[stack.length - 1] <= 9) {
          number = number + stack.pop() * Math.pow(10, count++);
        }
        let sum = "";
        while (number > 0) {
          sum += str;
          number--;
        }
        stack.push(sum);
        break;
      }
      default: {
        if (Number(s[i]) >= 0 && Number(s[i]) <= 9) {
          stack.push(Number(s[i]));
        } else {
          stack.push(s[i]);
        }
      }
    }
  }
  return stack.join("");
};
thinkfurther commented 3 years ago

思路

遇到[就把前面的字符串和数字压入stack,存储当前[]内的字符,直到遇见],则弹出stack,把重复次数的当前字符增加在前字符后面

代码

class Solution:
    def decodeString(self, s: str) -> str:        
        k_number = 0        
        resultString = ""        
        decoded_string = []        
        for char in s:
            if char.isnumeric():
                k_number = 10 * k_number + int(char)
            elif char == "[":
                decoded_string.append(resultString)
                decoded_string.append(k_number)
                k_number = 0
                resultString = ""
            elif char == "]":
                current_k = decoded_string.pop() 
                currentString = decoded_string.pop()
                resultString = currentString + current_k * resultString

            else:
                resultString += char
        return resultString

复杂度

时间复杂度:O(N)

空间复杂度:O(N)

chen445 commented 3 years ago

思路

using stack to keep track result, iterate each element into stack, if you see "]", start to pop until you see the "[".

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack=[]
        for e in s:
            if e=="]":
                temp=[]
                while stack[-1] != "[":
                    temp.append(stack.pop())
                stack.pop()
                count=0
                order=1
                while stack and stack[-1].isnumeric():
                    count+=int(stack.pop())*order
                    order*=10
                for i in range (count):
                    stack.extend(temp[::-1])
            else:
                stack.append(e)
        return "".join(stack)

复杂度

T: O(n) S: O(n)

zol013 commented 3 years ago

思路: 遇到】之前一直进栈, 遇到】之后开始出栈解码string,重复的string再依次进栈。 Python 3 code:

  class Solution:
       def decodeString(self, s: str) -> str:
              stack = []
              for char in s:
                   if char != ']':
                       stack.append(char)
                    else:
                         cur_str = ''
                         itr_iter = ''
                         while stack and stack[-1] != '[':
                               cur_str = stack.pop() + cur_str
                                stack.pop()
                          while stack and stack[-1].isdigit():
                               str_iter = stack.pop() + str_iter
                               int_iter = int(str_iter)
                           stack.append(cur_str * int_iter)
              return ''.join(stack)

Time complexity: O(N) N = length of decoded string Space Complexity: O(N)

hengistchan commented 3 years ago

代码

function decodeString(s: string): string {
  let stack: string[] = [], i = 0, length = s.length, res = ''
  while(i < length) {
    if(s[i] === ']') {
      let str = '', time: string | number = '', t = ''
      while(stack[stack.length - 1] !== '[') {
        str = stack.pop() + str
      }
      stack.pop()
      while(stack.length && stack[stack.length - 1].charCodeAt(0) >= '0'.charCodeAt(0) && stack[stack.length - 1].charCodeAt(0) <= '9'.charCodeAt(0)) {
        time = stack.pop() + time
      }
      stack.push(str.repeat(+time))
    } else {
      stack.push(s[i])
    }
    i++
  }
  return stack.join('')
};
qixuan-code commented 3 years ago

LC 394. Decode String

没有思路,把答案默写了一遍

python代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = [] 
        for i in s:
            if i == ']':
                strs = ''
                repeat_number = ''
                while stack and stack[-1] !='[':
                    strs = stack.pop()+strs
                stack.pop() #pop out'[]'

                while stack and stack[-1].isdigit():
                    repeat_number = repeat_number + stack.pop()

                stack.append(int(repeat_number)*strs)

            else:
                stack.append(i)
        return "".join(stack)

复杂度分析

joeytor commented 3 years ago

思路

遍历所有的字母

如果是 [, 0-9, a-z 的情况, 直接放入栈中

如果是 ] 的情况, 说明要开始出栈找出 单词 word 和 [ 前面的数字

向前pop, 每次加到 word 中 知道栈顶元素为 [ 代表 word 已经全部 pop 完了

pop 一次, 将栈中的 [ pop 出

继续 pop 得到栈中的数字, 有两种情况

  1. 如果 len(stack) == 0 代表 pop 完了, 此时 count 是完整的
  2. 如果 stack[-1] 不是 digit 代表 pop 完了, 此时 count 也是完整的

最后将 count * word 得到新的 string 并放入栈中

最后将栈中元素按相反顺序变成 string 即可

代码

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

        stack = []
        i = 0

        for c in s:
            if c == "]":
                count = ''
                word = ''
                # get word
                while stack[-1] != "[":
                    word = stack.pop() + word
                stack.pop() # pop out [
                # get num
                while len(stack) > 0 and stack[-1].isdigit():
                    count = stack.pop() + count
                stack += int(count) * word
            else:
                stack.append(c)

        return ''.join(stack)

复杂度

时间复杂度: O(n) 遍历一次单词, 栈里每个元素最多也是操作常数次

空间复杂度: O(n) 栈最大可以达到 O(n) 的大小

doveshnnqkl commented 3 years ago

思路

遍历字符串,除了"]" ,其他一律入栈(数字可能需要拼接后再入栈),遇到"]" 开始出栈,从栈顶开始出栈直到遇到"[",拼接出栈的这部分字母,再出栈一个就是这部分字母出现的次数,组合成字符串后重新入栈。最后将栈里所有字符拼接

代码

空间复杂度: O(n)

ghost commented 3 years ago

题目

  1. Decode String

思路

stack

代码

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []

        for c in s:
            if c == ']':
                sub_s = ''
                while(stack and stack[-1]!='['):
                    sub_s = stack.pop() + sub_s

                stack.pop()

                num = 0
                count = 0
                while(stack and stack[-1].isnumeric()):
                    num = num * 10 ** count + int(stack.pop())   
                    count+=1
                stack.append(sub_s*num)
                print(stack)       
            else:
                stack.append(c)

        return ''.join(stack)

复杂度

Space: O(N) Time: O(N)

hwpanda commented 3 years ago
const decodeString = function (s, i = 0) {
    let letter = /[a-z]/i;
    let number = /[0-9]/;
    let openBracket = '[';
    let closedBracket = ']';

    let result = '';
    let counter = '';

    while (i < s.length) {
        if (letter.test(s[i])) {
            result += s[i];
            i++;
        } else if (number.test(s[i])) {
            counter += s[i];
            i++;
        } else if (s[i] === openBracket) {
            const [window, nextIndex] = decodeString(s, i + 1);

            result += window.repeat(Number(counter));

            counter = '';
            i = nextIndex;
            continue;
        } else if (s[i] === closedBracket) {
            return [result, i + 1];
        }
    }
};
taojin1992 commented 3 years ago

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

Understand:

1 <= s.length <= 30
s consists of lowercase English letters, digits, and square brackets '[]'.
s is guaranteed to be a valid input.
All the integers in s are in the range [1, 300].

Input: s = "3[a2[c]]"
Output: "accaccacc"

k is guaranteed to be a positive integer

you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k.

Plan:

2 stacks, Stack<StringBuilder>, Stack<Integer> 

k can be greater than 10

if we see digit, build the complete integer (curFreq * 10 + s.charAt(curIndex) - '0')

if we see letter, build the complete string (by curStr.append(s.charAt(curIndex));)

if we see [, push curStr and curFreq into respective stacks, reset

*if we see ], 
curStr is the string to repeat
pop the top string, append the repeated string after it, it becomes the curStr

Review:

Input: s = "a3[a2[c]]e"
Output: "aaccaccacce"

c

a   2
a   3

acc

a  3

curStr: aaccaccacc

curStr: aaccaccacce

Evaluate:

Time: O(decoded res length)

Space: O(decoded res length)

Code:

class Solution {
    public String decodeString(String s) {
        if (s.length() == 1) return s;
        Stack<Integer> freqStack = new Stack<>();
        Stack<StringBuilder> strStack = new Stack<>();

        int curIndex = 0;
        StringBuilder curStr = new StringBuilder();
        int curFreq = 0;   

        while (curIndex < s.length()) {
            if (Character.isLetter(s.charAt(curIndex))) {
                curStr.append(s.charAt(curIndex));
            }
            else if (Character.isDigit(s.charAt(curIndex))) {
                curFreq = curFreq * 10 + s.charAt(curIndex) - '0';
            }
            else if (s.charAt(curIndex) == '[') {
                strStack.push(curStr);
                curStr = new StringBuilder();

                freqStack.push(curFreq);
                curFreq = 0;
            } else if (s.charAt(curIndex) == ']') {  // this part needs caution
                StringBuilder temp = curStr; // temp is the str to repeat
                curStr = strStack.pop();

                StringBuilder resStr = new StringBuilder();
                int freq = freqStack.pop();

                for (int i = 0; i < freq; i++) {
                    curStr.append(temp);
                }

            }
            curIndex++;
        }
        return curStr.toString();
    }
}
QiZhongdd commented 3 years ago

思路

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

linearindep commented 3 years ago

【思路】用两个stack记录,一个记录string,一个记录数字。遍历string,碰到左括号[就往前看数字,算出结果,存入另一个stack中,碰到右括号就不停pop,直到发现左括号,这样就算出了substring,再pop出已经通过左括号算好的次数,形成有效的长度,在放回stack中,这样下一个括号迭代也可以把这个弄好的string放入计算。

但是这样其实弄复杂了。题解好像是在遍历string的时候,碰到数字就可以直接计算,每次往前*10就可以了,碰到左括号就直接加入int stack更方便了。少了一次while pop。[机智 【复杂度】O(n)

public String decodeString(String s) {
        Stack<Character> num = new Stack<>();
        Stack<Integer> each = new Stack<>();
        Stack<String> decode = new Stack<>();
        String ans = "";

        for(int i = 0; i< s.length(); i++){
            Character temp = s.charAt(i);
            if(Character.isDigit(temp)){
                num.push(temp);
            }else if(temp == ']'){
                String curr = decode.pop();
                String local = "";
                String total = "";

                while(!curr.equals("[") ){
                    local = curr + local;
                    curr = decode.pop();
                }
                int times = each.pop();
                for(int j = 0; j<times; j++){
                    total = total+local;
                }
                decode.push(total);
            }else if(temp == '['){
                decode.push(temp+"");
                Character curr3 = num.pop();
                int pos = 1;
                int sum = curr3-'0';
                while(curr3!='['&& !num.isEmpty()) {
                    pos = pos *10;
                    curr3 = num.pop();
                    int now = curr3-'0';
                    sum += pos * now;

                }
                each.add(sum);
            }else{
                decode.push(temp+"");
            } 
        }

        while(!decode.isEmpty()){
            ans =decode.pop() + ans ;
        }
        return ans;

    }
florenzliu commented 3 years ago

Explanation

Python

class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for ch in s:
            if ch == "]":
                curr = ""
                while stack[-1] != "[":
                    curr = stack.pop() + curr
                stack.pop()
                num = ""
                while stack and stack[-1].isdigit():
                    num = stack.pop() + num
                currStr = curr * int(num)
                stack.append(currStr)
            else:
                stack.append(ch)    
        return "".join(stack)

Complexity

learning-go123 commented 3 years ago

思路

默认写入栈,从内部往外面解开
1.遇到 ] 就回去先把所有字母弹出并且反转
2.在弹出数字。 根据数字复制字母在回写入栈,重复以上两步

代码

Go Code:


func decodeString(s string) string {
    var stack []byte
    for i := 0; i < len(s); i++ {
        c := s[i]
        if c == 93 {
            var d []byte
            for stack[len(stack)-1] != 91 {
                size := len(stack) - 1
                d = append(d, stack[size])
                stack = stack[:size]
            }
            d = reverse(d)

            // 剔除[
            stack = stack[:len(stack)-1]
            digit := 1
            num := 0
            for len(stack) != 0 && stack[len(stack)-1] <= 57 {
                size := len(stack) - 1
                num += int(stack[size]-48) * digit
                digit *= 10
                stack = stack[:size]
            }

            for j := 1; j <= num; j++ {
                stack = append(stack, d...)
            }
        } else {
            stack = append(stack, c)
        }

    }

    return string(stack)
}

func reverse(s []byte) []byte {
    n := len(s)
    for i := 0; i < n/2; i++ {
        s[i], s[n-i-1] = s[n-i-1], s[i]
    }
    return s
}

复杂度分析

令 n 为数组长度。

jinmenghan commented 3 years ago

题目地址()

394. 字符串解码

题目描述

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

编码规则为: 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"

前置知识

思路

代码

Java Code:


  public static String decodeString(String s) {
        StringBuilder sb = new StringBuilder(s);
        while (sb.indexOf("[") != -1) {
            int leftIndex = sb.lastIndexOf("[");
            int rightIndex = sb.indexOf("]", leftIndex);
            String str = sb.substring(leftIndex + 1, rightIndex);
            int i = leftIndex - 1, count = 0, base = 1;
            while (i >= 0 && Character.isDigit(sb.charAt(i))) {
                count += base * (sb.charAt(i) - '0');
                base *= 10;
                i--;
            }
            StringBuilder tmp = new StringBuilder();
            for (int j = 0; j < count; j++) tmp.append(str);
            sb = sb.replace(i + 1, rightIndex + 1, tmp.toString());
        }
        return sb.toString();
    }

复杂度分析

令 n 为数组长度。

machuangmr commented 3 years ago

思路

复杂度

ChiaJune commented 3 years ago

思路

从左至右遍历:

  1. 如果是数字,则累加到count上(字符串操作);
  2. 如果是字母啥的,则累加到result上(字符串操作);
  3. 如果是[,则将当前的count和result组成数组的一项([count, result])push到stack中,同时清空result和count,此操作主要用于记录当前信息,以方便遇到]的时候计算。
  4. 如果是],stack进行pop()操作得到[count, res],然后进行数据组装,注意组装顺序。

    代码

    var decodeString = function(s) {
    let i = 0, size = s.length;
    var result = '';
    var count = '';
    var stack = [];
    while (i < size) {
    var c = s[i];
    if (c === '[') {
      stack.push([count, result]);
      result = '';
      count = '';
    } else if (c === ']') {
      var res = stack.pop();
      result = res[1] + result.repeat(Number(res[0]));
    } else if (/\d/.test(c)) {
      // 数字
      count += c;
    } else {
      // 字母
      result += c;
    }
    i++;
    }
    return result;
    };

复杂度

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

Daniel-Zheng commented 3 years ago

思路

模拟Stack

代码(C++)

class Solution {
public:
    string decodeString(string s) {
        string res = "";
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == ']') {
                string str = "";
                string cnt = "";
                while (res.back() != '[') {
                    str = res.back() + str;
                    res.pop_back();
                }
                res.pop_back();
                while (!res.empty() && isdigit(res.back())) {
                    cnt = res.back() + cnt;
                    res.pop_back();
                }
                int a = stoi(cnt);
                while (a > 0) {
                    res.append(str);
                    a--;
                }
            } else {
                res.push_back(s[i]);
            }
        }
        return res;
    }
};

复杂度分析

RonghuanYou commented 3 years ago

思路: 用两个stack,一个记录出现的数字,一个记录字符串。 当遇到[的时候,就存储数字和字符串。 当遇到]的时候,就出栈,实现从内到外的这个打印效果。 其他时候就Concatenate char。

class Solution:
    def decodeString(self, s: str) -> str:
        numS, chaS = [], []
        num, output = 0, ""
        for c in s:
            if c.isdigit():
                num = num * 10 + int(c)
            elif c == '[':
                numS.append(num)
                chaS.append(output)
                num, output = 0, ""
            elif c == ']':
                output = chaS.pop() + output * numS.pop()
            else:
                output += c
        return output

time complexity: O(N) space complexity: O(N)

ryzhao5 commented 3 years ago

思路: 建立一个栈,将每个字母遍历,如果没有遇到],就加入栈中,如果遇到[,则先弹出字母,再弹出数字,根据字母和数字经过处理后加入栈中,直到遍历完字母,栈中即为结果

class Solution {
    public String decodeString(String s) {
        Stack<Character> stack = new Stack<>();
        for(char c: s.toCharArray()){
            if(c != '['){
                stack.push(c);
            }
            else{
                StringBuffer sb = new StringBuffer();
                while(!stack.isEmpty() && Character.isLetter(stack.peek())){
                    sb.insert(0, stack.pop());
                }

                String sub = sb.toString();
                stack.pop();

                sb = new StringBuffer();

                while(!stack.isEmpty() && Character.isDigit(stack.peek())){
                    sb.insert(0, stack.pop());
                }

                int count = Integer.parseInt(sb.toString());

                while(count > 0){
                    for(char ch: sub.toCharArray()){
                        stack.push(ch);
                    }
                    count--;
                }
            }
        }

        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty()) {
            res.insert(0, stack.pop());
        }

        return res.toString();
    }
}

时间复杂度空间复杂度均为O(N)