题目
注意题目对输入进行了规范,左方括号前必定是正整数,反之,正整数必定在左方括号前。原始字符串中没有数字。
解题
解题一:栈操作
multi = 10 * multi + parseInt(c);
一是因为如果不把 c 转换成整数类型,运算会变成字符串的拼接;二是存在 100[leetcode] 这样的输入,所以要乘10再加。
// javascript
var decodeString = function(s) {
let strStack = [], resArr = [], multi = 0;
for (let c of s) {
if (c === "[") {
strStack.push([multi, resArr.slice()]);
multi = 0;
resArr = [];
} else if (c === "]") {
let [curMulti, prevArr] = strStack.pop();
let curArr = [];
for (let j = 0; j < curMulti; j++) curArr = curArr.concat(resArr);
resArr = prevArr.concat(curArr);
}
else if (isNaN(c) === false) multi = 10 * multi + parseInt(c);
else resArr.push(c);
}
return resArr.join("");
};
本来以为用字符数组的空间效率会更高,但是从 js 提交结果来看,直接拼接字符串的空间效率更高:
// javascript
var decodeString = function(s) {
let strStack = [], multi = 0, res = "";
for (let c of s) {
if (c === '[') {
strStack.push([multi, res]);
res = "";
multi = 0;
}
else if (c === "]") {
let [curMulti, prev] = strStack.pop();
res = prev + res.repeat(curMulti);
}
else if (isNaN(c) === false) multi = 10 * multi + parseInt(c);
else res += c;
}
return res;
};
解题二:递归
一是要注意 dfs 要传入索引并且返回索引来控制 while 循环,if (s[i] === "[")
里用 multi = 0;
是因为 s = "3[a]2[bc]"
时,如果 multi 没有被重置,遍历到 2 时,multi 是 3,运算后 multi 变为 32;也可以理解为 multi 要重复的字符串已经操作好了,没有必要再进行存储。
// javascript
var decodeString = function(s) {
return dfs(s, 0);
};
var dfs = function(s, i) {
let multi = 0, res = "";
while (i < s.length) {
if (s[i] === "[") {
let tmp = "";
[i, tmp] = dfs(s, i + 1);
res += tmp.repeat(multi);
multi = 0;
}
else if (s[i] === "]") {
return [i, res];
}
else if (isNaN(s[i]) === false) multi = 10 * multi + parseInt(s[i]);
else res += s[i];
i++;
}
return res;
};