一条仅包含字母‘A’-‘Z’的消息用下列的方式加密成数字 'A' -> 1↵'B' -> 2↵...↵'Z' -> 26
现在给出加密成数字的密文,请判断有多少种解密的方法。例如:
给出的密文为“12”,可以解密为"AB"(1 2) 或者"L"(12).所以密文"12"的解密方法是2种.
思路:动态规划
最大的字母为26,所以最多用两位来构造一个字母。
D[i]为第i个位置的所有解密字符串。
D[i]= (D[i-1] . i解密出的字母) & (D[i - 2] . i-1和i两位一起解密出的字母)
<?php
function numDecodings($s) {
$arrMap = [
'A' => 1,
'B' => 2,
'C' => 3,
'D' => 4,
'E' => 5,
'F' => 6,
'G' => 7,
'H' => 8,
'I' => 9,
'J' => 10,
'K' => 11,
'L' => 12,
'M' => 13,
'N' => 14,
'O' => 15,
'P' => 16,
'Q' => 17,
'R' => 18,
'S' => 19,
'T' => 20,
'U' => 21,
'V' => 22,
'W' => 23,
'X' => 24,
'Y' => 25,
'Z' => 26
];
$arrNewMap = array_flip($arrMap);
$num = strlen($s);
$D[-1] = [];
for ($i = 0; $i < $num; $i ++) {
if ($i == 0) {
$D[$i] = [$arrNewMap[$s[$i]]];
}
foreach ($D[$i - 1] as $item) {
$D[$i][] = $item . $arrNewMap[$s[$i]];
}
if (intval($s[$i-1] . $s[$i]) <= 26) {
if ($i == 1) {
$D[$i][] = $arrNewMap[$s[$i-1] . $s[$i]];
}
foreach ($D[$i - 2] as $item) {
$D[$i][] = $item . $arrNewMap[$s[$i-1] . $s[$i]];
}
}
}
print_r($D[$num - 1]);
}
$s = '121';
numDecodings($s);