LeetCode 738、746、62

77 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

本文包含下面几题:

  1. 当且仅当每个相邻数上的数字xy满足x<=y时,我们称这个数是单调递增的。给定一个数,返回小于或等于n的最大数字,且数字呈单调递增。
  2. 给定一个花费数组,数组中的元素代表爬到第i个楼梯的最小花费,求到达顶部的最低花费。
  3. 给定一个数组,求从数组左上角到右下角的路径的个数。

解题思路

LeetCode 738 单调递增的数字

希望数字单调递增,那么我们可以从数字的最后一个数开始遍历,如果这个数大于前一个数就继续,否则就将前一个数字减一,这是很容易想到的,但这样只能保证前一个数小于等于当前数,并且这个数也不是最大的,所以正确做法是将前一个数减一的同时,还需要将当前数置9,可得代码如下:

public int monotoneIncreasingDigits(int n) {
    String s = String.valueOf(n);
    char[] c = s.toCharArray();
    int start = s.length();
    for(int i=start-1;i>0;i--){
        if(c[i]<c[i-1]){
            c[i-1]--;
            start = i;
        }
    }
    for(int i=start;i<s.length();i++){
        c[i] = '9';
    }
    return Integer.parseInt(String.valueOf(c));
}

LeetCode 746 使用最小花费爬楼梯

本题和简单的爬楼梯类似,但本题计算的是爬楼梯的花费,所关注的就不是爬上楼梯还有多少种方法了,而每次爬到某个楼梯都是可以由前一个和前两个进行确定的,可得代码如下:

public int minCostClimbingStairs(int[] cost) {
    if(cost.length==1) return cost[0];
    if(cost.length==2) return Math.min(cost[0], cost[1]);
    // dp[i] 爬到i处的最低花费
    int[] dp = new int[cost.length];
    dp[0] = cost[0];
    dp[1] = cost[1];
    for(int i=2;i<cost.length;i++){
        dp[i] = Math.min(dp[i-1], dp[i-2]) + cost[i];
    }
    return Math.min(dp[cost.length-1], dp[cost.length-2]);
}

LeetCode 62 不同路径

很简单的一个动态规划,可以说是动态规划使用二维数组的入门题了,只需要确定最终的状态是有两种:从左边来的和从上面来的。将这个思路用到所有格子即可,可得代码如下:

public int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    for(int i=0;i<n;i++){
        dp[0][i] = 1;
    }
    for(int i=0;i<m;i++){
        dp[i][0] = 1;
    }
    for(int i=1;i<m;i++){
        for(int j=1;j<n;j++){
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
        }
    }
    return dp[m-1][n-1];
}

最终的时间复杂度位O(mn)O(mn)