LeetCode 394.字符串解码

144 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目:给定一个经过编码的字符串,要求返回解码后的字符串。

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

题目假设输入的字符串总是有效的,并且字符串中数字全部表示重复次数。

例如:输入s = "3[a]2[bc]"

​ 输出:"aaabcbc"

解题思路

题目看起来并不难,但对细节和基础的考验并不少。

看到左括号和右括号,首先考虑是否可以使用栈来解决本题。基本思路,用上面的s作为示例:

  1. 将字符串转换为字符数组。
  2. 将字符依次入栈,直到遇到字符]
  3. 依次出栈,使用StringBuilder将字符接收,直到栈顶元素为[
  4. [出栈。
  5. 获取重复次数。因为题目保证了所有的数字都只表示重复的次数,因此可以直接把得到的数字作为重复次数。考虑数字不一定为个位数,因此在数字出栈的时候需要考虑十位百位等情况。此处在每次出栈都判断当前栈顶是否是数字,如果是则一直出栈,使用StringBuilder接收。
  6. 之后将之前接收到的字符按照重复次数依次入栈。
  7. 循环上面的步骤。最终的栈中元素即为最终答案。

根据上面思路可得代码如下:

public String decodeString(String s) {
    ArrayDeque<Character> stack = new ArrayDeque<>();
    for(int i=0;i<s.toCharArray().length;i++){
        if(s.charAt(i)!=']'){
            stack.push(s.charAt(i));
        }else {
            StringBuilder sb = new StringBuilder();
            while(!stack.isEmpty()&&stack.peek()!='['){
                sb.insert(0, stack.pop());
            }
            String str = sb.toString();
            stack.pop();
            
            sb = new StringBuilder();
            while(!stack.isEmpty()&&Character.isDigit(stack.peek())){
                sb.insert(0, stack.pop());
            }
            int repeat = Integer.parseInt(sb.toString());
            while (repeat>0){
                for(char ch: str.toCharArray()){
                    stack.push(ch);
                }
                repeat--;
            }
        }
    }
    StringBuilder sb = new StringBuilder();
    while(!stack.isEmpty())
        sb.insert(0, stack.pop());

    return sb.toString();
}