leecode 394. 字符串解码 java版本
Posted 落叶归根
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leecode 394. 字符串解码 java版本相关的知识,希望对你有一定的参考价值。
2020-05-29 17:07:06
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例:
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".
作者:jyd
链接:https://leetcode-cn.com/problems/decode-string/solution/decode-string-fu-zhu-zhan-fa-di-gui-fa-by-jyd/
来源:力扣(LeetCode)
解法一:辅助栈法
本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。
算法流程:
构建辅助栈 stack, 遍历字符串 s 中每个字符 c;
1.当 c 为数字时,将数字字符转化为数字 cnt,用于后续倍数计算;
2.当 c 为字母时,在 str 尾部添加 c;
3.当 c 为 [ 时,将当前 cnt 和 str 入栈,并分别置空置 :
记录此 [ 前的临时结果 str 至栈,用于发现对应 ] 后的拼接操作;
记录此 [ 前的倍数 cnt 至栈,用于发现对应 ] 后,获取 cnt × [...] 字符串。
进入到新 [ 后,str 和 cnt 重新记录。
4.当 c 为 ] 时,stack 出栈,拼接字符串 str= last_res + cur_multi * res,其中:
last_res是上个 [ 到当前 [ 的字符串,例如 "3[a2[c]]" 中的 a;
cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 "3[a2[c]]" 中的 2。
返回字符串 str。
复杂度分析:
时间复杂度 O(N)O(N),一次遍历 s;
空间复杂度 O(N)O(N),辅助栈在极端情况下需要线性空间,例如 2[2[2[a]]]。
java算法是根据 他们分析才写出来的 ,做算法题,个人感觉最重要的是每次做了题收获是什么,这题的难点就是【】的嵌套,最初的想法是先用stack来做,可以解决单层嵌套,
后来看他们都在用LinkedList 双向链表,来解决可能更简洁一些,相信我题刷的多了也能有自己的更好的思路吧··加油!! 2020-05-29 18:22:31
1 import java.util.*; 2 class Solution { 3 public String decodeString(String s) { 4 LinkedList<Integer> stacki = new LinkedList<>();// 5 LinkedList<String> stacks = new LinkedList<>();//存放【之前的字符串 6 StringBuilder str = new StringBuilder(); 7 int cnt =0; 8 for(Character c : s.toCharArray()){ 9 if(c<=\'z\'&&c>=\'a\'||c<=\'Z\'&&c>=\'A\'){ 10 str.append(c+""); 11 } 12 if(c<=\'9\'&&c>=\'0\'){ 13 cnt = cnt*10 + c-\'0\'; 14 } 15 if(c==\'[\'){ 16 stacks.addLast(str.toString());//把str存入栈 17 stacki.addLast(cnt);//把cnt存入栈 18 str=new StringBuilder(); 19 cnt=0; 20 } 21 if(c==\']\'){ 22 int n = stacki.removeLast(); 23 StringBuilder st = new StringBuilder(); 24 for(int j=0;j<n;j++) st.append(str); 25 str= new StringBuilder(stacks.removeLast() + st) ;// 3[a2[c]] 的a + cc 26 } 27 } 28 return str.toString(); 29 } 30 }
这是之前写的代码,边界条件太多,思路混淆,不知怎么下手
1 import java.util.*; 2 class Solution { 3 public String decodeString(String s) { 4 Stack stack=new Stack(); 5 if(s.length()<1) return ""; 6 char[] c = s.toCharArray(); 7 String res = ""; 8 String rest = ""; 9 for(int i=0;i<c.length;i++){ 10 if(c[i]==\'[\'){ 11 res = res+rest; 12 rest=""; 13 } 14 if(c[i]!=\']\'){ 15 if(c[i]<\'z\'&&c[i]>\'a\'||c[i]<\'Z\'&&c[i]>\'A\'&&rest.length()>1){ 16 for(Character ch : rest.toCharArray()){ 17 stack.push(ch); 18 } 19 rest="";} 20 stack.push(c[i]); 21 } 22 if(c[i]==\']\'){ 23 while((char)stack.peek()!=\'[\'){ 24 rest= stack.pop()+rest; 25 } 26 stack.pop(); 27 int cnt = Integer.parseInt(stack.pop().toString()); 28 int j=1; 29 while(!stack.isEmpty()&&(char)stack.peek()>=\'0\' 30 &&(char)stack.peek()<=\'9\'){ 31 j *=10; 32 cnt = cnt+Integer.parseInt(stack.pop().toString())*j; 33 } 34 String str = rest; 35 while(cnt>1){ 36 rest = str + rest; 37 cnt--; 38 } 39 } 40 } 41 if(rest.length()>1)res = res+rest; 42 String t =""; 43 while(!stack.isEmpty()){ 44 t = stack.pop()+t; 45 } 46 res = res + t; 47 return res; 48 } 49 }
心痛···,代码写的很糟糕。
以上是关于leecode 394. 字符串解码 java版本的主要内容,如果未能解决你的问题,请参考以下文章