Decode String

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

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

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

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

Examples:

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

思路:这里用两个stack,一个int stack用来存之前的number,一个stringbuilder stack用来存之前的string;

遇见左括号,将之前的num和stringbuilder push进去,并清零;

遇见右括号,将之前的string和num pop出来,然后现在的string要重复k次;这是最简洁的;

为什么要用stringbuilder stack,是因为用stringbuilder,可以用stringbuilder连起来前后string,然后每次只用存stringbuilder就可以了。而且prestringbuilder , number, [stringbuilder]; 重复后面的stringbuilder就可以了;

class Solution {
    public String decodeString(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        // Input: s = "3[a]2[bc]"
        // Output: "aaabcbc"
        // prestringbuilder, num [stringbuilder]
        StringBuilder sb = new StringBuilder();
        Stack<Integer> instack = new Stack<>();
        Stack<StringBuilder> sbstack = new Stack<>();
        
        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 == '[') {
                instack.push(num);
                sbstack.push(sb);
                sb = new StringBuilder();
                num = 0;
            } else if(c == ']') {
                int k = instack.pop();
                StringBuilder pre = sbstack.pop();
                while(k > 0) {
                    pre.append(sb);
                    k--;
                }
                sb = pre;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

方法2: 如果面试官允许用java自带的stack,那么可以用dfs来写,这个很好写。
3[XXXXXX] 中间的 用dfs来解决,假设后面的已经做好了,那么就append num次就行了,记住num这个时候要清空为0;

class Solution {
    public String decodeString(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        Deque<Character> queue = new LinkedList<>();
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            queue.offer(c);
        }
        return helper(queue);
    }
    
    private String helper(Deque<Character> queue) {
        StringBuilder sb = new StringBuilder();
        int num = 0;
        while(!queue.isEmpty()) {
            char c = queue.poll();
            if(Character.isDigit(c)) {
                num = num * 10 + c - '0';
            } else if(c == '[') {
                String sub = helper(queue);
                for(int i = 0; i < num; i++) {
                    sb.append(sub);
                }
                num = 0;
            } else if(c == ']') {
                break;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值