LeetCode --- 字符串系列 --- 解码字母到整数映射

解码字母到整数映射

题目

给你一个字符串 s,它由数字('0' - '9')和 '#' 组成。

我们希望按下述规则将 s 映射为一些小写英文字符:

  1. 字符('a' - 'i')分别用('1' - '9')表示。
  2. 字符('j' - 'z')分别用('10#' - '26#')表示。 
  3. 返回映射之后形成的新字符串。

题目数据保证映射始终唯一。


示例

示例 1:

输入:s = "10#11#12"
输出:"jkab"
解释:"j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".
示例 2:

输入:s = "1326#"
输出:"acz"
示例 3:

输入:s = "25#"
输出:"y"
示例 4:

输入:s = "12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"
输出:"abcdefghijklmnopqrstuvwxyz"

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/decrypt-string-from-alphabet-to-integer-mapping

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


解题思路

能想到的就是使用正则替换 `1、2、3、...、 10#、11#、...、26#` 为相对应的 字母
而且还必须是先替换带有 `#` 后缀的,这就需要从 `26#、25#、 ... 2、1` 反向进行替换

1、从 0 到 26(不含26) 循环,构造` 数组 sArr`
数组每个元素是个对象,包含字母以及字母对应的规则数字
[
    // fromCharCode 拿到字母 z y x ...
    { label: 'z', index: 26 },
    { label: 'y', index: 25 },
    { label: 'x', index: 24 },
    ...
]

2、遍历 `数组 sArr`, `j - z` 对应的数字后面有附加 `#`
所以判断, `num` 大于等于 10 的数组元素的 `num` 需要加上后缀 `#`

3、使用正则全局替换成对应的字母

或者

力扣较好题解

1、遍历字符串

2、判断当前 `字符位` 向后两位是否为 `#`
2、1 
    若不是,则这段 `字符位` 位置的字符串可以映射为一个字母
    截取这段字符串,用于下面使用 `fromCharCode` 替换成字母
2、2
    若是,则这段从 `字符位` 到  `字符位` +2 的字符串可以映射为一个字母
    截取这段字符串,用于下面使用 `fromCharCode` 替换成字母
    遍历数组下标设置为 `字符位` +2

3、针对截取到的字符串,先用 parseInt 处理成纯数字
再使用 `fromCharCode` 替换成字母,最后变量 res 拼接

或者

力扣较好题解

1、简单明了,使用正则全局替换 --- /(dd#|d)/g
dd# 匹配 10#、11#、12#、 ...、26#
d 匹配  1、2、3、...、9

2、使用 replace 方法的迭代函数,在迭代函数里面做 数字-->字母 的转换
这里也要注意,需要将匹配到的字符串使用 parseInt 转换成纯数字
再使用 `fromCharCode` 替换成字母

题解

let freqAlphabets = function(s) {
    let sArr = []
    for (let i = 0; i < 26; i++) {
        sArr[i] = { 
            // fromCharCode 倒序拿到字母 z y x ...
            label: String.fromCharCode((25 - i) + 97), 
            // 本题目字母对应的规则数字
            num: 26 - i 
        }
    }
    // 倒序排列字母,方便后面正则替换时候,优先从 z y x ... 开始
    // 即替换字符串从 26# 25# 24# ... 开始
    // [
    //     { label: 'z', index: 26 },
    //     { label: 'y', index: 25 },
    //     { label: 'x', index: 24 },
    //     ...
    // ]
    sArr.forEach(item => {
        // 遍历数组 sArr, j - z 对应的数字后面有附加 #
        // 所以这里判断,num 大于等于 10 的数组元素的 num 需要加上后缀 #
        let num = item.num
        if (num > 9) {
            num += '#'
        }
        // 最后使用正则进行全局替换
        s = s.replace(new RegExp(num, 'g'), item.label)
    })
    return s
}

或者

力扣较好题解

let freqAlphabets = function(s) {
    let res = ''
    let n = ''
    // 遍历字符串
    for (let i = 0; i < s.length; i++){
        // 判断当前 字符位 向后两位是否为 #
        if (s[i + 2] !== '#') {
            // 若不是,则这段 i 位置的字符串可以映射为一个字母
            // 截取这段字符串,用于下面使用 fromCharCode 替换成字母
            n = s[i]
        } else{
            // 若是,则这段从 i 到  i+2 的字符串可以映射为一个字母
            // 截取这段字符串,用于下面使用 fromCharCode 替换成字母
            n = s.substr(i, 3)
            i = i + 2
        }
        // 使用 fromCharCode 替换成字母,变量 res 拼接
        res += String.fromCharCode(parseInt(n) + 96)
    }
    return res
}

或者

力扣较好题解

let freqAlphabets = function(s) {
    // 简单明了,使用正则全局替换
    // dd# 匹配 10#、11#、12#、 ...、26#
    // d 匹配  1、2、3、...、9
    // replace 使用 n => String.fromCharCode(parseInt(n) + 96) 迭代函数,返回数字对应字母
    return s.replace(/(dd#|d)/g, n => {
        // n 为 1、2、3、...、 10#、11#、12#、...、26#
        // 所以需要使用 parseInt 转换成纯数字
        return String.fromCharCode(parseInt(n) + 96)
    })
}

都读到最后了、留下个建议如何
原文地址:https://www.cnblogs.com/linjunfu/p/12652054.html