Problem:
A message containing letters from A-Z is being encoded to numbers using the following mapping:
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
Analysis:
when doing a code problem, I think we can begin code until we figure out the right solution, or we just waste time.
how to make sure we are clear? draw it, write in psydo code, or even write in speaking lanuage.
In this problem, we need to pay attention on the return situation.
method1:
dfs, (recursive)
time complexity T(n) = 2T(n-1) + C, so O(n^2)
space complexity: O(n)
method2:
dfs+DP
storing the value into an array, will save lots of time.
time complexity: O(n)
space complexity: O(n)
public class Solution1 {
public static int numDecodings(String s) {
// corner case
if (s.length() == 0 || s == null) return 0;
return numDecode(s.toCharArray(), 0);
}
public static int numDecode(char[] arr, int startPos) {
// we should pay attention on the return situation
if (startPos == arr.length) return 1;
int count = 0;
if (arr[startPos] != '0') {
count += numDecode(arr, startPos+1);
}
if (isValid(arr, startPos)) {
count += numDecode(arr, startPos+2);
}
return count;
}
// there is nothing new here, just check whether two characters are in 10-26
public static boolean isValid(char[] arr, int startPos) {
if (startPos + 1 > arr.length - 1) return false;
char a = arr[startPos];
char b = arr[startPos + 1];
int aNum = a - '0';
int bNum = b - '0';
if (aNum * 10 + bNum <= 26 && aNum * 10 + bNum >= 10) {
return true;
}
return false;
}
// in this method, we will use Dynamic Programming
// we can store the value in the array, so we don't need to calculate it iteratively
public static int numDecodings1(String s) {
if (s.length() == 0 || s == null) return 0;
// we need to store the value when s.length() == 0, so we create the array with length + 1
int[] note = new int[s.length() + 1];
Arrays.fill(note, -1);
return numDecode1(note, s.toCharArray(), 0);
}
public static int numDecode1(int[] note, char[] arr, int startPos) {
if (note[startPos] != -1) return note[startPos];
if (startPos == arr.length) {
note[startPos] = 1;
return 1;
}
int count = 0;
if (arr[startPos] != '0') {
count += numDecode1(note, arr, startPos+1);
}
if (isValid(arr, startPos)) {
count += numDecode1(note, arr, startPos+2);
}
note[startPos] = count;
System.out.println(note[0]);
return count;
}
public static void main(String[] args) {
String s = "226";
System.out.println(numDecodings1(s));
}
}