880. 索引处的解码字符串

265 阅读2分钟

给定一个编码字符串 S。请你找出 **解码字符串 并将其写入磁带。解码时,从编码字符串中 每次读取一个字符 ,并采取以下步骤:

  • 如果所读的字符是字母,则将该字母写在磁带上。
  • 如果所读的字符是数字(例如 d),则整个当前磁带总共会被重复写 d-1 次。

现在,对于给定的编码字符串 S 和索引 K,查找并返回解码字符串中的第 K 个字母。

示例 1:

输入: S = "leet2code3", K = 10
输出: "o"
解释:解码后的字符串为 "leetleetcodeleetleetcodeleetleetcode"。字符串中的第 10 个字母是 "o"

示例 2:

输入: S = "ha22", K = 5
输出: "h"
解释:解码后的字符串为 "hahahaha"。第 5 个字母是 "h"

示例 3:

输入: S = "a2345678999999999999999", K = 1
输出: "a"
解释: 解码后的字符串为 "a" 重复 8301530446056247680 次。第 1 个字母是 "a"

题解

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
// 逆向模拟,由于题目规模较大,要用 BigInt
// 举例:S = "leet2code3", K = 10
// 1. 正向求出 S 的总长度 size = 36
// 2. 逆向遍历 S,区分遇到数字和字母的情况
// 遇到 3, k = 10 % 36 = 10, size = 36 / 3 = 12;
// 遇到 e, k = 10 % 12 = 10, size--, size = 11
// 遇到 d, k = 10 % 11 = 10, size--, size = 10
// 遇到 o, k = 10 % 10 = 0, k === 0, 返回 'o'

var decodeAtIndex = function (s, k) {
    let len = s.length;
    let size = 0n;
    k = BigInt(k);
    // 计算出字符串长度 遇到字符时 size ++ 遇到数字 size * v
    for (let i = 0; i < len; i++) {
        const v = s[i];
        if (isNum(v)) {
            size *= BigInt(v);
        } else {
            size++;
        }
    }
    // 逆向遍历字符S
    for (let i = len - 1; i >= -1; i--) {
        k = k % size;
        const v = s[i];
        if (isCh(v) && k === 0n) {
            return v;
        }
        // size 值区分当前值时字符还是数字
        if (isNum(v)) {
            size /= BigInt(v);
        } else {
            size--;
        }
    }

};

function isCh(x) {
    return /[a-z]/.test(x);
}

function isNum(x) {
    return /[2-9]/.test(x);
}

来源:力扣(LeetCode)

链接:leetcode.cn/problems/de…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。