LeetCode Decode Way Series Problems
091 decode ways:
given a number String, return the number of unique number of ways to decode that.
Input: “226”
Output: 3
Explanation: It could be decoded as “BZ” (2 26), “VF” (22 6), or “BBF” (2 2 6).
At the first glance of this problem, we know that this problem is a dp problem.
in this problem, the dp equation is dp[i] = dp[i-1] + (dp[i-2]), and dp[i-2] is optional if substring(i-2,i) is within the range of [10, 26].
based on this, the solution is pretty simple:
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' ? 0 : 1;
for(int i = 2; i <= n; i++){
int first = Integer.valueOf(s.substring(i-1,i));
int second = Integer.valueOf(s.substring(i-2,i));
//deal with dp[i-1]
if(first >= 1 && first <= 9){
dp[i] += dp[i-1]; //why it is not dp[i] += 9 * dp[i-1]? because we are given a fixed string and every position is fixed with number
}
//deal with dp[i-2]
if(second >= 10 && second <= 26){
dp[i] += dp[i-2];
}
}
return dp[n];
}
}
LC639 decode ways2:
this problem is a follow up of decode ways1. and this time, we added a wildcard in the input String: “*”, which represents any numbers from 1 to 9.
class Solution {
public int numDecodings(String s) {
long[] dp = new long[s.length() + 1];
dp[0] = 1;
if (s.charAt(0) == '0') { //if head is 0 then the string is invalid
return 0;
}
dp[1] = s.charAt(0) == '*' ? 9 : 1;
for (int i = 2; i <= s.length(); i++) {
char first = s.charAt(i-2);
char second = s.charAt(i-1);
//deal with dp[i-1]
if (second == '*') {
dp[i] += 9 * dp[i-1];
} else if (second > '0') {
dp[i] += dp[i-1];
} //if second == '0', we didn't do anything since this can't form any valid number
//deal with dp[i-2]
if (first == '*') {
if (second == '*') {
dp[i] += 15 * dp[i-2];
} else if (second <= '6') {
dp[i] += 2 * dp[i-2];
} else {
dp[i] += dp[i-2];
}
} else if (first == '1' || first == '2') {
if (second == '*') {
if (first == '1') {
dp[i] += 9 * dp[i-2];
} else if (first == '2') {
dp[i] += 6 * dp[i-2];
}
} else if (Integer.parseInt(s.substring(i-2, i)) <= 26) {
dp[i] += dp[i-2];
}
} //if first is neither * or 1 or 2, then we can't see the s.substring(i-2,i) as a number,so we do nothing
dp[i] %= 1000000007;
}
return (int)dp[s.length()];
}
}
this solution seems complex than the decode ways1, but there are basically the same idea.
we still divide the solution into to parts, dp[i] deal with dp[i-1] and dp[i] deal with dp[i-2].
when dp[i] deals with dp[i-1], that means we only needs to consider s.charAt(i-1), there are three senerios: s.charAt(i-1) == ‘*’ / ‘0’ / not ‘0’, and each one of them we will have a reaction.
when dp[i] deals with dp[i-2], that means we needs to consider the combination of s.charAt(i-1) and s.charAt(i-2), so:
when s.charAt(i-2) == ‘*’:
if s.charAt(i-1) == ‘’
if s.charAt(i-1) <= ‘6’
if s.charAt(i-1) > ‘6’
when s.charAt(i-2) == ‘1’ || s.charAt(i-2) == ‘2’:
if s.charAt(i-1) == '’
if s.charAt(i-2) == ‘1’
if s.charAt(i-2) == ‘2’
if s.charAt(substring(i-2, i) <= 26) :
…
when s.charAt(i-2) > 2:
…

浙公网安备 33010602011771号