小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?
"HG[3|B[2|CA]]F"
"HGBCACABCACABCACAF"
HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF
S的长度<=1000;
S仅包含大写字母、[、]、|;
解压后的字符串长度不超过100000;
压缩递归层数不超过10层;
//java 25ms
import java.util.*;
public class Solution {
public String compress(String str) {
char[] chars=str.toCharArray();
return helper(chars,0,chars.length-1);
}
private String helper(char[] chars, int i, int j) {
StringBuilder sb = new StringBuilder();
while (i<=j){
if(chars[i]!='['){
sb.append(chars[i]);
i++;
}else if(chars[i]=='['){
i++;
//数字
int tmp=i+1;
int n=chars[i]-'0';
while (chars[i]!='|'){
i++;
}
for (int k =tmp ; k < i; k++) {
n=n*10+chars[k]-'0';
}
//寻找匹配的窗口
int p=i+1;
int cnt=1;
while (p<=j&&cnt!=0){
if(chars[p]=='['){
cnt++;
}else if(chars[p]==']'){
cnt--;
}
p++;
}
//递归
String s=helper(chars,i+1,p-2);
//添加【】内的字符串
for (int k = 0; k < n; k++) {
sb.append(s);
}
i=p;
}
}
return sb.toString();
}
} public class Solution {
int len = 0;
public String compress (String str) {
len = str.length();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < len; i++) {
if(str.charAt(i) == '['){
// 调用解析函数,返回一个列表,列表第一个是匹配到的串
// 第二个是匹配玩后下一个坐标值
List next = solver(str, i+1);
sb.append(next.get(0));
i = (Integer)next.get(1);
} else sb.append(str.charAt(i));
}
return sb.toString();
}
public List solver(String str, int idx) {
// 列表第一个返回匹配到的字符串,第二个返回最后的索引
List ans = new ArrayList();
StringBuilder sb = new StringBuilder();
// 先得到数字m
int l = idx, r = idx;
while(r < len && str.charAt(r) != '|') {
r++;
}
int m = Integer.parseInt(str.substring(l, r));
// 递归解析后面的部分
if(r++ < len) {
for(int i = r;i < len;i++) {
if(str.charAt(i) == '[') {
// 碰到'['就开始解析,并设置i的值
List next = solver(str,i+1);
sb.append(next.get(0));
i = (Integer)next.get(1);
} else if(str.charAt(i) == ']') {// 找到右边边界,结束
r = i;
break;
} else sb.append(str.charAt(i));// 正常字符,直接添加
}
}
// 添加m串字串
String tmp = sb.toString();
for(int i = 0;i < m-1;i++) {
sb.append(tmp);
}
// 封装结果返回
ans.add(sb.toString());
ans.add(r);
return ans;
}
}