ID:394.字符串解码

116 阅读1分钟

考点:栈

题目链接

思路

比较简单,自己做的,注意考虑括号括起的字符串中仍然可能包含括号的情况

var decodeString = function(s) {
    let res = "";
    let leftCount = 0; // 左括号数量
    for(let i = 0; i < s.length; i++) {
        // 不是数字也不是[]
        if(isNaN(+s[i]) && s[i] !== '[' && s[i] !== ']') {
            res += s[i];
        } else if(!isNaN(+s[i])) { // 是数字
            // 记录重复数字
            let numStr = s[i];
            // 注意数字有可能有多位,所以要一直找到'['之前为止
            while(s[++i] !== '[') numStr += s[i];
            // 重置左括号数量
            leftCount = 0;
            // 将字符串重复数字转化成number类型
            const count = +numStr;
            // 记录要重复的字符串的起始位置和结束位置
            let start = i, end = start;
            // 结束位置不断向右增加
            while(end++) {
                // 遇到左括号leftCount加一
                // 可以看作是括号进栈,每当有一个右括号进栈的时候出栈一个左括号
                if(s[end] === '[') leftCount++;
                else if(s[end] === ']') leftCount--;
                // 当左括号数量为0的时候,说明中间的字符串完全匹配
                // 不会出现原字符串为a[b[c]]时误将a[b[c]看作是要重复的字符串的情况
                // 即保证字符串中的括号匹配是合法的
                if(!leftCount) break;
            }
            // 当前循环的下标跳转到结束位置
            i = end;
            // 中间的字符串仍然可能存在括号,因此递归调用函数
            res += decodeString(s.substring(start + 1, end)).repeat(count);
        }
    }
    return res;
};