【JavaScript】【dp】Leetcode每日一题-解码方法
【JavaScript】Leetcode每日一题-解码方法
【题目描述】
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
'A' -> 1
'B' -> 2
...
'Z' -> 26
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"11106" 可以映射为:
-
"AAJF" ,将消息分组为 (1 1 10 6)
-
"KJF" ,将消息分组为 (11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6" 和 "06" 在映射中并不等价。
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。
示例1:
输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。
示例2:
输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
示例3:
输入:s = "0"
输出:0
解释:没有字符映射到以 0 开头的数字。
含有 0 的有效映射是 'J' -> "10" 和 'T'-> "20" 。
由于没有字符,因此没有有效的方法对此进行解码,因为所有数字都需要映射。
示例4:
输入:s = "06"
输出:0
解释:"06" 不能映射到 "F" ,因为字符串含有前导 0("6" 和 "06" 在映射中并不等价)。
提示:
1 <= s.length <= 100
s 只包含数字,并且可能包含前导零。
【分析】
朴素dfs - TLE
let nums;
let len;
let char = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26']
/**
* @param {string} s
* @param {int} index
*/
var dfs = function(s, index){
if(index == len){
nums++;
return;
}
if(char.includes(s[index])){
dfs(s, index+1);
}
console.log(s.slice(index, index+2));
if(index+1 < len && char.includes(s.slice(index, index+2))){
dfs(s, index+2);
}
};
/**
* @param {string} s
* @return {number}
*/
var numDecodings = function(s) {
nums = 0;
len = s.length;
dfs(s, 0);
return nums;
};
动态规划dp
-
思路:
状态转移方程:
\[nums[i] = single + double\\ single=\begin{cases} 0, & s[i]在10以外\\ num[i-1], & s[i]在10以内 \end{cases} \\ double=\begin{cases} 0, & s[i-1:i+1]在范围以外\\ num[i-2], & s[i-1:i+1]在范围以内 \end{cases} \]边界情况:
if(s[0] == '0') //如果第一位为0,则不可能存在解码结果 return 0; nums[0] = 1; if(char10.includes(s.slice(0, 2))) //如果前两位在范围内,num[1]可能结果+1 nums[1]++; if(char9.includes(s[1])) //如果第二位在10以内,num[1]可能结果+1 nums[1]++;
-
代码
let char9 = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] let char10 = ['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26'] /** * @param {string} s * @return {number} */ var numDecodings = function(s) { let len = s.length; let nums = new Array(len).fill(0); if(s[0] == '0'){ return 0; } nums[0] = 1; if(char10.includes(s.slice(0, 2))){ nums[1]++; } if(char9.includes(s[1])){ nums[1]++; } for(var i=2;i