解码字母到整数映射
题目
给你一个字符串 s,它由数字('0' - '9')和 '#' 组成。
我们希望按下述规则将 s 映射为一些小写英文字符:
- 字符('a' - 'i')分别用('1' - '9')表示。
- 字符('j' - 'z')分别用('10#' - '26#')表示。
- 返回映射之后形成的新字符串。
题目数据保证映射始终唯一。
示例
示例 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)
})
}