LeetCode91,LeetCode64

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];
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38595487/article/details/82379233