LeetCode91. 解码方法
题目
一条包含字母 A-Z
的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
示例 1:
输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。
示例 2:
输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
分析
要处理好0这个数字, 0 不能解码 如果是 0 00 01 07 这种都是没有办法解码的,返回0。
字符串如果是 0 开头, 或者字符串中包含 00 的都直接返回0。
我创建了一个count整数数组,来记录每一位数字上最多的解码数。
先让 a = s.charAt(i), b = s.charAt(i-1), sum = b * 10 + a ,sum也就是相邻的两个数字连起来的数值。
如果sum = 0 的话,也就是两个0相邻,则 return 0
如果sum > 26 的话,当a=0,也就是30 40 这种情况,不能解码直接return0;a!=0时, 则证明相邻数字不能组成一个字母,这个字母最多的解码数也就是它上个字母的最多解码数count[i] = count[i-1]
如果 0<sum<=26的话, 当a=0 也就是 10 20 这种情况,也就是说a这个0啊,只能和前面的1或者是2相连才可以解码,也就是说0对应的这个位置的解码数和前一个数字的解码数一样count[i] = count[i-1];但是当 a !=0 时, 也就是19 25 这种情况,那么它可以从前面两个数字来解码,count[i] = count[i-1]+coutn[i-2]。
另外当b=0的时候,count[i]=count[i-1],前提是sum!=0。
代码
class Solution {
public int numDecodings(String s) {
if (s.length() == 0 || s.equals("0")) return 0;
if (s.length() == 1 ) return 1;
int[] count = new int[s.length()+1];
count[0] = 1;
if (s.charAt(0) == '0') return 0;
count[1] = 1;
for (int i = 1; i < s.length(); i++) {
int a = s.charAt(i) - '0';
int b = s.charAt(i-1) - '0';
int sum = b * 10 + a;
if ( sum == 0 )
return 0;
if (b == 0){
count[i+1] = count[i];
continue;
}
if ( sum <= 26)
if ( a == 0) count[i+1] =count[i-1];
else count[i+1] = count[i] + count[i-1];
if (sum > 26){
if (sum% 10 == 0) return 0;
count[i+1] = count[i];
}
}
return count[s.length()];
}
}
提交里面有一份很清楚的代码 贴上来, 思路和上面也类似,也比较容易理解。
class Solution {
public int numDecodings(String s) {
int[] dp = new int[s.length()+1];
dp[1] = s.charAt(0)=='0'?0:1;
dp[0] = 1;
for(int i=2;i<=s.length();i++){
if(s.charAt(i-1) != '0'){
dp[i] += dp[i-1];
}
if(s.charAt(i-2)=='1' || (s.charAt(i-2)=='2' && s.charAt(i-1)<'7')){
dp[i] += dp[i-2];
}
}
return dp[s.length()];
}
}
LeetCode64. 最小路径和
题目
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
分析
很简单的一道动态规划问题,根据之前的路径,来判断当前的最小路径。
比如:
1 3 1
1 5 1
4 2 1
第一个位置,00位置 最小路径为1, 01位置最小路径伟 1+3 = 4, 02 位置 最小路径 1+4 = 5,
10位置最小路径 1+1=2 , 20位置最小路径 2+4=6 ,
11位置最小路径为 11位置的5 + min(01位置的4,10位置的2) = 7, 12位置最小路径,12位置的1 + min(11位置的7,02位置的5) = 6
21位置最小路径为 21位置的2 + min(20位置的6,11位置的7) = 8, 22位置最小路径, 22位置的1 + min(21位置的8, 12位置的6) = 7。
所以最小路径为 7。
1 4 5
2 7 6
6 8 7
代码
class Solution {
public int minPathSum(int[][] grid) {
int row = grid.length;
int col = grid[0].length;
int[][] path = new int[row][col];
path[0][0] = grid[0][0];
for (int i = 1; i < col; i++)
path[0][i] = path[0][i-1] + grid[0][i];
for (int i = 1; i < row; i++)
path[i][0] = path[i-1][0] + grid[i][0];
for (int i = 1; i < row; i++)
for (int j = 1; j < col; j++)
path[i][j] = Math.min(grid[i][j]+path[i-1][j], grid[i][j]+path[i][j-1]);
return path[row-1][col-1];
}
}