0
点赞
收藏
分享

微信扫一扫

LeeCode刷题简记(八)

忆北文学摄影爱好员 2022-04-17 阅读 59

LeeCode动态规划

        本质优雅的穷举,用数组存答案消重叠,

动态规划基本概念

1.定义

动态规划与分治法类似,其基本思想也是将待求问题分解成若干子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合与用动态规划求解的问题,经分解得到的子问题往往不是互相独立的,若使用分治法来解决这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间,然而,不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。如果能够保存已经解决子问题的答案,在需要的时候再找出这些已经求得的答案,这样就可以避免大量的重复运算,从而得到多项式时间算法。

为了达到上述目的,可以使用一个表来记录所有已经解决子问题的答案。不管子问题以后是否被用到,只要它被计算过,就将结果填入表中。这就是动态规划的基本思想。

2、无后效性

如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响。即未来与过去无关。例如,一旦f(n)确定,“我们如何凑出f(n)”就再也用不着了。要求出f(15),只需要知道f(14),f(10),f(4)的值,而f(14),f(10),f(4)是如何算出来的,对之后的问题没有影响。

3、最优子结构

回顾我们对f(n)的定义:我们记“凑出n所需的最少钞票数量”为f(n)。f(n)的定义就已经蕴含了“最优”。利用w=14,10,4的最优解,我们即可算出w=15的最优

       大问题最优解可以由小问题的最优解推出。
 

Solution62不同路径

 

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

 

Solution64最小路径和

Solution46全排列

class Solution {
    public static void process(int[] str, int i, ArrayList<String> res){
        if (i == str.length){
            res.add(String.valueOf(str));
        }
        for (int j = i; j < str.length;j++){
            swap(str, i, j);
            process(str, i + 1,res);
            swap(str, i, j);
        }
    }

    public static void swap(int[] chs, int i , int j){
        int tmp = chs[i];
        chs[i] = chs[j];
        chs[j] = tmp;
    }
}

Solution198打家劫舍

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0];
        if(n == 1){
            return dp[0];
        }
        dp[1] = Math.max(nums[0],nums[1]);
        for (int i = 2;i < n;i++){
            dp[i] = Math.max(dp[i - 1],dp[i - 2] + nums[i]);
            
        }
        return dp[n - 1];
    }
}

Solution213打家劫舍Ⅱ

 环状的数组,可以分开讨论

class Solution {
    public int rob(int[] nums) {
        int len = nums.length;
        if(len == 1){
            return nums[0];
        }
        if(len == 2){
            return Math.max(nums[0],nums[1]);
        }
        //偷一不偷尾
        int[] dp1 = new int[len];
        //偷尾不偷一
        int[] dp2 = new int[len];
        dp1[0] = nums[0];
        dp1[1] = Math.max(nums[0], nums[1]);
        dp2[1] = nums[1];
        dp2[2] = Math.max(nums[1], nums[2]);
        for(int i = 2; i < len - 1;i++){
            dp1[i] = Math.max(dp1[i-1],dp1[i-2]+nums[i]);
        } 
        for(int i = 3; i < len; i++){
            dp2[i] = Math.max(dp2[i-1],dp2[i-2]+nums[i]);
        }
        return Math.max(dp1[len-2],dp2[len-1]);
    }
}

举报

相关推荐

0 条评论