动态规划

本文深入讲解动态规划的核心概念,提供Fibonacci数列、路径计数等经典问题的解决方案,并详细解析三角形最小路径和、最大子序列和、打家劫舍等实战题目,助您掌握动态规划算法。

视频教程:B站、网易云课堂、腾讯课堂
代码地址:Gitee、Github
存储地址:
百度云-提取码:
Google云

1.Fibonacci数列

2.路径计数

3.最长公共子序列

4.三角形最小路径

5.最大子序列和

6.打家劫舍

递归代码模板:

public void  recur(int level , int param){
    // terminator
    if (level > MAX_LEVEL){   // 1.递归结束终止条件
       //proccess result
       return ;
    }
    //process current logic  
    process(level,param);   //2.处理当前逻辑
    //drill down
    recur( levell:level+1,newParam);//3.下探下一层
    // restore current status  4.恢复当前状态
}


分治代码模板:

def divide_conquer(problem,param1,param2,...):
    # recursion terminator  递归终止条件
    if problem is  None:
       print_result
       return
    # prepare data  拆分子问题
    data = prepare_data(problem)
    subproblems = split_problem(problem,data)
 
    # conquer subproblems   调用子问题的递归函数
    subresult1 = self.divide_conquer(subproblems[0],p1,...)
    subresult2 = self.divide_conquer(subproblems[1],p1,...)
    subresult3 = self.divide_conquer(subproblems[2],p1,...)
    ...
    # process and generate the final result  合并结果
    result = process_result(subresult1,subresult2,subresult3,...)

    # revert the current level states  恢复当前状态





动态规划:分治+最优子结构(使用递归)
在这里插入图片描述

1.人肉递归低效、很累
3.数学归纳法思维(抵制人肉递归的诱惑)
2.找到最近最简方法,将其拆解成可重复解决的问题
本质:寻找重复性—>计算机指令集


在这里插入图片描述


  1. 爬楼梯

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/


class Solution {
    public int climbStairs(int n) {
        if(n <= 0) return 0;
        if(n ==1 ) return 1;
        if(n ==2 ) return 2;

        int one_step_before = 2;
        int two_steps_before = 1;
        int all_ways = 0;

        for (int i = 2;i<n;i++) {
            all_ways = one_step_before +two_steps_before;
            two_steps_before = one_step_before;
            one_step_before = all_ways;

        }
        return all_ways;
    }
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 三角形最小路径和

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int[] A = new int[triangle.size()+1];
        for(int i=triangle.size()-1;i>=0;i--){
            for(int j=0;j<triangle.get(i).size();j++){
                A[j] = Math.min(A[j],A[j+1])+triangle.get(i).get(j);
            }
        }
        return A[0];
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最大子序和

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int maxSubArray(int[] A) {
            int n = A.length;
            int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];
            dp[0] = A[0];
            int max = dp[0];
            
            for(int i = 1; i < n; i++){
                dp[i] = A[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);
                max = Math.max(max, dp[i]);
            }
            
            return max;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 乘积最大子数组

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int maxProduct(int[] A) {
        if (A.length == 0) {
            return 0;
        }
        
        int maxherepre = A[0];
        int minherepre = A[0];
        int maxsofar = A[0];
        int maxhere, minhere;
        
        for (int i = 1; i < A.length; i++) {
            maxhere = Math.max(Math.max(maxherepre * A[i], minherepre * A[i]), A[i]);
            minhere = Math.min(Math.min(maxherepre * A[i], minherepre * A[i]), A[i]);
            maxsofar = Math.max(maxhere, maxsofar);
            maxherepre = maxhere;
            minherepre = minhere;
        }
        return maxsofar;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. Coin Change

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int coinChange(int[] coins, int amount) {
        if(amount<1) return 0;
        return helper(coins, amount, new int[amount]);
    }

    private int helper(int[] coins, int rem, int[] count) { // rem: remaining coins after the last step; count[rem]: minimum number of coins to sum up to rem
        if(rem<0) return -1; // not valid
        if(rem==0) return 0; // completed
        if(count[rem-1] != 0) return count[rem-1]; // already computed, so reuse
        int min = Integer.MAX_VALUE;
        for(int coin : coins) {
            int res = helper(coins, rem-coin, count);
            if(res>=0 && res < min)
                min = 1+res;
        }
        count[rem-1] = (min==Integer.MAX_VALUE) ? -1 : min;
        return count[rem-1];
    }
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 打家劫舍

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int rob(int[] num) {
        int prevNo = 0;
        int prevYes = 0;
        for (int n : num) {
            int temp = prevNo;
            prevNo = Math.max(prevNo, prevYes);
            prevYes = n + temp;
        }
        return Math.max(prevNo, prevYes);
    }
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 打家劫舍 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

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


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 买卖股票的最佳时机

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int maxProfit(int[] prices) {
        int maxCur = 0, maxSoFar = 0;
        for(int i = 1; i < prices.length; i++) {
            maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]);
            maxSoFar = Math.max(maxCur, maxSoFar);
        }
        return maxSoFar;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 买卖股票的最佳时机 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int maxProfit(int[] prices) {
            int i = 0, buy, sell, profit = 0, N = prices.length - 1;
            while (i < N) {
                while (i < N && prices[i + 1] <= prices[i]) i++;
                buy = prices[i];

                while (i < N && prices[i + 1] > prices[i]) i++;
                sell = prices[i];

                profit += sell - buy;
            }
            return profit;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 买卖股票的最佳时机 III

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/
public class Solution {
    public int maxProfit(int[] prices) {
        int hold1 = Integer.MIN_VALUE, hold2 = Integer.MIN_VALUE;
        int release1 = 0, release2 = 0;
        for(int i:prices){                              // Assume we only have 0 money at first
            release2 = Math.max(release2, hold2+i);     // The maximum if we've just sold 2nd stock so far.
            hold2    = Math.max(hold2,    release1-i);  // The maximum if we've just buy  2nd stock so far.
            release1 = Math.max(release1, hold1+i);     // The maximum if we've just sold 1nd stock so far.
            hold1    = Math.max(hold1,    -i);          // The maximum if we've just buy  1st stock so far. 
        }
        return release2; ///Since release1 is initiated as 0, so release2 will always higher than release1.
    }
}




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最佳买卖股票时机含冷冻期

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length <= 1) return 0;
    
        int b0 = -prices[0], b1 = b0;
        int s0 = 0, s1 = 0, s2 = 0;
    
        for(int i = 1; i < prices.length; i++) {
            b0 = Math.max(b1, s2 - prices[i]);
            s0 = Math.max(s1, b1 + prices[i]);
            b1 = b0; s2 = s1; s1 = s0; 
        }
        return s0;
    }
};


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 买卖股票的最佳时机 IV

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
   public int maxProfit(int k, int[] prices) {
        int len = prices.length;
        if (k >= len / 2) return quickSolve(prices);
        
        int[][] t = new int[k + 1][len];
        for (int i = 1; i <= k; i++) {
            int tmpMax =  -prices[0];
            for (int j = 1; j < len; j++) {
                t[i][j] = Math.max(t[i][j - 1], prices[j] + tmpMax);
                tmpMax =  Math.max(tmpMax, t[i - 1][j - 1] - prices[j]);
            }
        }
        return t[k][len - 1];
    }
    

    private int quickSolve(int[] prices) {
        int len = prices.length, profit = 0;
        for (int i = 1; i < len; i++)
            // as long as there is a price gap, we gain a profit.
            if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1];
        return profit;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 买卖股票的最佳时机含手续费

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/


class Solution {
    public int maxProfit(int[] prices, int fee) {
            if (prices.length <= 1) return 0;
            int days = prices.length, buy[] = new int[days], sell[] = new int[days];
            buy[0]=-prices[0]-fee;
            for (int i = 1; i<days; i++) {
                buy[i] = Math.max(buy[i - 1], sell[i - 1] - prices[i] - fee); // keep the same as day i-1, or buy from sell status at day i-1
                sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]); // keep the same as day i-1, or sell from buy status at day i-1
            }
            return sell[days - 1];
        }
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 完全平方数

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for(int i = 1; i <= n; ++i) {
            int min = Integer.MAX_VALUE;
            int j = 1;
            while(i - j*j >= 0) {
                min = Math.min(min, dp[i - j*j] + 1);
                ++j;
            }
            dp[i] = min;
        }		
        return dp[n];
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 编辑距离

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int minDistance(String word1, String word2) {
        int m = word1.length();
        int n = word2.length();
        
        int[][] cost = new int[m + 1][n + 1];
        for(int i = 0; i <= m; i++)
            cost[i][0] = i;
        for(int i = 1; i <= n; i++)
            cost[0][i] = i;
        
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(word1.charAt(i) == word2.charAt(j))
                    cost[i + 1][j + 1] = cost[i][j];
                else {
                    int a = cost[i][j];
                    int b = cost[i][j + 1];
                    int c = cost[i + 1][j];
                    cost[i + 1][j + 1] = a < b ? (a < c ? a : c) : (b < c ? b : c);
                    cost[i + 1][j + 1]++;
                }
            }
        }
        return cost[m][n];
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 跳跃游戏

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public boolean canJump(int[] A) {
        int max = 0;
        for(int i=0;i<A.length;i++){
            if(i>max) {return false;}
            max = Math.max(A[i]+i,max);
        }
        return true;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 跳跃游戏 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
   public int jump(int[] A) {
	int jumps = 0, curEnd = 0, curFarthest = 0;
	for (int i = 0; i < A.length - 1; i++) {
		curFarthest = Math.max(curFarthest, i + A[i]);
		if (i == curEnd) {
			jumps++;
			curEnd = curFarthest;
		}
	}
	return jumps;
}
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 不同路径

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

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


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 不同路径 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int width = obstacleGrid[0].length;
        int[] dp = new int[width];
        dp[0] = 1;
        for (int[] row : obstacleGrid) {
            for (int j = 0; j < width; j++) {
                if (row[j] == 1)
                    dp[j] = 0;
                else if (j > 0)
                    dp[j] += dp[j - 1];
            }
        }
        return dp[width - 1];
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 不同路径 III

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    int res = 0, empty = 1, sx, sy, ex, ey;
    public int uniquePathsIII(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 0) empty++;
                else if (grid[i][j] == 1) {
                    sx = i;
                    sy = j;
                }
            }
        }
        dfs(grid, sx, sy);
        return res;
    }

    public void dfs(int[][] grid, int x, int y) {
        if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] < 0)
            return;
        if (grid[x][y] == 2) {
            if (empty == 0) res++;
            return;
        }
        grid[x][y] = -2;
        empty--;
        dfs(grid, x + 1, y);
        dfs(grid, x - 1, y);
        dfs(grid, x, y + 1);
        dfs(grid, x, y - 1);
        grid[x][y] = 0;
        empty++;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 零钱兑换

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/


public class Solution {
    public int coinChange(int[] coins, int amount) {
        if(amount<1) return 0;
        return helper(coins, amount, new int[amount]);
    }

    private int helper(int[] coins, int rem, int[] count) { // rem: remaining coins after the last step; count[rem]: minimum number of coins to sum up to rem
        if(rem<0) return -1; // not valid
        if(rem==0) return 0; // completed
        if(count[rem-1] != 0) return count[rem-1]; // already computed, so reuse
        int min = Integer.MAX_VALUE;
        for(int coin : coins) {
            int res = helper(coins, rem-coin, count);
            if(res>=0 && res < min)
                min = 1+res;
        }
        count[rem-1] = (min==Integer.MAX_VALUE) ? -1 : min;
        return count[rem-1];
    }
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 零钱兑换 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/


class Solution {
    public int change(int amount, int[] coins) {
        int[] dp = new int[amount + 1];
        dp[0] = 1;
        for (int coin : coins) {
            for (int i = coin; i <= amount; i++) {
                dp[i] += dp[i-coin];
            }
        }
        return dp[amount];
    }
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最长有效括号

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int longestValidParentheses(String s) {
        Stack<Integer> stack = new Stack<Integer>();
        int max=0;
        int left = -1;
        for(int j=0;j<s.length();j++){
            if(s.charAt(j)=='(') stack.push(j);            
            else {
                if (stack.isEmpty()) left=j;
                else{
                    stack.pop();
                    if(stack.isEmpty()) max=Math.max(max,j-left);
                    else max=Math.max(max,j-stack.peek());
                }
            }
        }
        return max;
    }
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最小路径和

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
public int minPathSum(int[][] grid) {
	int m = grid.length;// row
	int n = grid[0].length; // column
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (i == 0 && j != 0) {
				grid[i][j] = grid[i][j] + grid[i][j - 1];
			} else if (i != 0 && j == 0) {
				grid[i][j] = grid[i][j] + grid[i - 1][j];
			} else if (i == 0 && j == 0) {
				grid[i][j] = grid[i][j];
			} else {
				grid[i][j] = Math.min(grid[i][j - 1], grid[i - 1][j])
						+ grid[i][j];
			}
		}
	}

	return grid[m - 1][n - 1];
}
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 解码方法

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int numDecodings(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int n = s.length();
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = s.charAt(0) != '0' ? 1 : 0;
        for (int i = 2; i <= n; i++) {
            int first = Integer.valueOf(s.substring(i - 1, i));
            int second = Integer.valueOf(s.substring(i - 2, i));
            if (first >= 1 && first <= 9) {
               dp[i] += dp[i-1];  
            }
            if (second >= 10 && second <= 26) {
                dp[i] += dp[i-2];
            }
        }
        return dp[n];
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最大正方形

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/
class Solution {
    public int maximalSquare(char[][] a) {
        if(a.length == 0) return 0;
        int m = a.length, n = a[0].length, result = 0;
        int[][] b = new int[m+1][n+1];
        for (int i = 1 ; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if(a[i-1][j-1] == '1') {
                    b[i][j] = Math.min(Math.min(b[i][j-1] , b[i-1][j-1]), b[i-1][j]) + 1;
                    result = Math.max(b[i][j], result); // update result
                }
            }
        }
        return result*result;
    }
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 矩形区域不超过 K 的最大数值和

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int maxSumSubmatrix(int[][] matrix, int k) {
        int m = matrix.length, n = matrix[0].length, ans = Integer.MIN_VALUE;
        long[] sum = new long[m+1]; // stores sum of rect[0..p][i..j]
        for (int i = 0; i < n; ++i) {
            long[] sumInRow = new long[m];
            for (int j = i; j < n; ++j) { // for each rect[*][i..j]
                for (int p = 0; p < m; ++p) {
                    sumInRow[p] += matrix[p][j];
                    sum[p+1] = sum[p] + sumInRow[p];
                }
                ans = Math.max(ans, mergeSort(sum, 0, m+1, k));
                if (ans == k) return k;
            }
        }
        return ans;
    }
    int mergeSort(long[] sum, int start, int end, int k) {
        if (end == start+1) return Integer.MIN_VALUE; // need at least 2 to proceed
        int mid = start + (end - start)/2, cnt = 0;
        int ans = mergeSort(sum, start, mid, k);
        if (ans == k) return k;
        ans = Math.max(ans, mergeSort(sum, mid, end, k));
        if (ans == k) return k;
        long[] cache = new long[end-start];
        for (int i = start, j = mid, p = mid; i < mid; ++i) {
            while (j < end && sum[j] - sum[i] <= k) ++j;
            if (j-1 >= mid) {
                ans = Math.max(ans, (int)(sum[j-1] - sum[i]));
                if (ans == k) return k;
            }
            while (p < end && sum[p] < sum[i]) cache[cnt++] = sum[p++];
            cache[cnt++] = sum[i];
        }
        System.arraycopy(cache, 0, sum, start, cnt);
        return ans;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 青蛙过河

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

Use map to represent a mapping from the stone (not index) to the steps that can be taken from this stone.

so this will be

[0,1,3,5,6,8,12,17]

{17=[], 0=[1], 1=[1, 2], 3=[1, 2, 3], 5=[1, 2, 3], 6=[1, 2, 3, 4], 8=[1, 2, 3, 4], 12=[3, 4, 5]}

Notice that no need to calculate the last stone.

On each step, we look if any other stone can be reached from it, if so, we update that stone’s steps by adding step, step + 1, step - 1. If we can reach the final stone, we return true. No need to calculate to the last stone.

Here is the code:

java版

/*
思路:

*/


class Solution {
    public boolean canCross(int[] stones) {
        if (stones.length == 0) {
        	return true;
        }
        
        HashMap<Integer, HashSet<Integer>> map = new HashMap<Integer, HashSet<Integer>>(stones.length);
        map.put(0, new HashSet<Integer>());
        map.get(0).add(1);
        for (int i = 1; i < stones.length; i++) {
        	map.put(stones[i], new HashSet<Integer>() );
        }
        
        for (int i = 0; i < stones.length - 1; i++) {
        	int stone = stones[i];
        	for (int step : map.get(stone)) {
        		int reach = step + stone;
        		if (reach == stones[stones.length - 1]) {
        			return true;
        		}
        		HashSet<Integer> set = map.get(reach);
        		if (set != null) {
        		    set.add(step);
        		    if (step - 1 > 0) set.add(step - 1);
        		    set.add(step + 1);
        		}
        	}
        }
        
        return false;
    } 
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 分割数组的最大值

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    public int splitArray(int[] nums, int m) {
        int max = 0; long sum = 0;
        for (int num : nums) {
            max = Math.max(num, max);
            sum += num;
        }
        if (m == 1) return (int)sum;
        //binary search
        long l = max; long r = sum;
        while (l <= r) {
            long mid = (l + r)/ 2;
            if (valid(mid, nums, m)) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return (int)l;
    }
    public boolean valid(long target, int[] nums, int m) {
        int count = 1;
        long total = 0;
        for(int num : nums) {
            total += num;
            if (total > target) {
                total = num;
                count++;
                if (count > m) {
                    return false;
                }
            }
        }
        return true;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 学生出勤记录 II

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

class Solution {
    static final int M = 1000000007;

    public int checkRecord(int n) {
        long[] PorL = new long[n + 1]; // ending with P or L, no A
        long[] P = new long[n + 1]; // ending with P, no A
        PorL[0] = P[0] = 1; PorL[1] = 2; P[1] = 1;

        for (int i = 2; i <= n; i++) {
            P[i] = PorL[i - 1];
            PorL[i] = (P[i] + P[i - 1] + P[i - 2]) % M;
        }
        
        long res = PorL[n];
        for (int i = 0; i < n; i++) { // inserting A into (n-1)-length strings
            long s = (PorL[i] * PorL[n - i - 1]) % M;
            res = (res + s) % M;
        }
        
        return (int) res;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 任务调度器

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

// (c[25] - 1) * (n + 1) + 25 - i  is frame size
// when inserting chars, the frame might be "burst", then tasks.length takes precedence
// when 25 - i > n, the frame is already full at construction, the following is still valid.
public class Solution {
    public int leastInterval(char[] tasks, int n) {

        int[] c = new int[26];
        for(char t : tasks){
            c[t - 'A']++;
        }
        Arrays.sort(c);
        int i = 25;
        while(i >= 0 && c[i] == c[25]) i--;

        return Math.max(tasks.length, (c[25] - 1) * (n + 1) + 25 - i);
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 回文子串

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
    int count = 0;
    
    public int countSubstrings(String s) {
        if (s == null || s.length() == 0) return 0;
        
        for (int i = 0; i < s.length(); i++) { // i is the mid point
            extendPalindrome(s, i, i); // odd length;
            extendPalindrome(s, i, i + 1); // even length
        }
        
        return count;
    }
    
    private void extendPalindrome(String s, int left, int right) {
        while (left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            count++; left--; right++;
        }
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 最小覆盖子串

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/

public class Solution {
public String minWindow(String s, String t) {
    if(s == null || s.length() < t.length() || s.length() == 0){
        return "";
    }
    HashMap<Character,Integer> map = new HashMap<Character,Integer>();
    for(char c : t.toCharArray()){
        if(map.containsKey(c)){
            map.put(c,map.get(c)+1);
        }else{
            map.put(c,1);
        }
    }
    int left = 0;
    int minLeft = 0;
    int minLen = s.length()+1;
    int count = 0;
    for(int right = 0; right < s.length(); right++){
        if(map.containsKey(s.charAt(right))){
            map.put(s.charAt(right),map.get(s.charAt(right))-1);
            if(map.get(s.charAt(right)) >= 0){
                count ++;
            }
            while(count == t.length()){
                if(right-left+1 < minLen){
                    minLeft = left;
                    minLen = right-left+1;
                }
                if(map.containsKey(s.charAt(left))){
                    map.put(s.charAt(left),map.get(s.charAt(left))+1);
                    if(map.get(s.charAt(left)) > 0){
                        count --;
                    }
                }
                left ++ ;
            }
        }
    }
    if(minLen>s.length())  
    {  
        return "";  
    }  
    
    return s.substring(minLeft,minLeft+minLen);
}
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

  1. 戳气球

国内站

java版

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

java版

/*
思路:

*/
class Solution {
public int maxCoins(int[] nums) {
    int[][] dp = new int[nums.length][nums.length];
    return maxCoins(nums, 0, nums.length - 1, dp);
}

public int maxCoins(int[] nums, int start, int end, int[][] dp) {
    if (start > end) {
        return 0;
    }
    if (dp[start][end] != 0) {
        return dp[start][end];
    }
    int max = nums[start];
    for (int i = start; i <= end; i++) {
        int val = maxCoins(nums, start, i - 1, dp) + 
                  get(nums, i) * get(nums, start - 1) * get(nums, end + 1) + 
                  maxCoins(nums, i + 1, end, dp);
                  
        max = Math.max(max, val);
    }
    dp[start][end] = max;
    return max;
}

public int get(int[] nums, int i) {
    if (i == -1 || i == nums.length) {
        return 1;
    }
    return nums[i];
}
}



/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

一 动态规划的实现及关键点

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二 例题解析:Fibonacci数列、路径计数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三 例题解析:最长公共子序列

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四 实战题目解析:三角形最小路径和

五 实战题目解析:最大子序列和

六 实战题目解析:打家劫舍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值