解密数字
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 36 ms, 内存: 14.9 MB
/**
* 解题思路:
* 1. 使用Java Stream处理密文,将数字转换为字符。
* 2. 使用递归或动态规划方法,通过Stream操作计算不同的解密方式。
*/
import java.util.stream.IntStream;
public class Solution {
public int numDecodings(String s) {
if (s == null || s.length() == 0) return 0;
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = s.charAt(0) != '0' ? 1 : 0;
IntStream.range(2, n + 1).forEach(i -> {
int oneDigit = Integer.parseInt(s.substring(i - 1, i));
int twoDigits = Integer.parseInt(s.substring(i - 2, i));
if (oneDigit >= 1 && oneDigit <= 25) dp[i] += dp[i - 1];
if (twoDigits >= 10 && twoDigits <= 25) dp[i] += dp[i - 2];
});
return dp[n];
}
}
解释
方法:
这个题解通过动态规划的方式解决问题。首先将数字转换为字符串,以便于访问每一位数字。定义dp(i)为从字符串的第i位到最后一位可以有多少种解码方式。如果当前位和下一位组成的数字在10到25之间,那么这两位可以被解码为一个字符,因此dp(i) = dp(i-1) + dp(i-2),即考虑当前位单独解码和与下一位一起解码的情况。如果不在这个范围内,只能单独解码,因此dp(i) = dp(i-1)。递归的基情况是当i小于等于0时,返回1,表示至少有一种解码方式。最终,dp(len(str(num))-1)给出了从第0位到最后一位的解码方式总数。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在动态规划解法中,为什么基情况设置为当i<=0时返回1,这里的逻辑是什么?
▷🦆
题解中提到如果两个数字组成的数在10到25之间可以解码为一个字符,但数字0如何处理,尤其是当它作为一个单独的数字存在时?
▷🦆
解法中提到递归的方式,但实际上是否使用了递归的调用栈,还是通过迭代配合记忆化完成的?
▷🦆
动态规划的边界条件是如何设置的,特别是如何处理字符串的最后一位或最后两位数字?
▷