Last updated on 2023年9月16日 早上
509. 斐波那契数(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : int fib (int n) { if (n <= 1 ){ return n; } vector<int > dp (n + 1 ) ; dp[0 ] = 0 ; dp[1 ] = 1 ; for (int i = 2 ;i <= n;i++){ dp[i] = dp[i - 1 ] + dp[i - 2 ]; } return dp[n]; } };
70. 爬楼梯(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : int climbStairs (int n) { if (n <= 1 ){ return n; } vector<int > dp (n + 1 ) ; dp[1 ] = 1 ; dp[2 ] = 2 ; for (int i = 3 ; i <= n;i ++){ dp[i] = dp[i - 1 ] + dp[i - 2 ]; } return dp[n]; } };
70. 爬楼梯(C++动态规划实现,优化空间的写法) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution {public : int climbStairs(int n) { if (n <= 1 ){ return n; } int dp[3 ]; dp[1 ] = 1 ; dp[2 ] = 2 ; for (int i = 3 ;i <= n;i++){ int sum = dp[1 ] + dp[2 ]; dp[1 ] = dp[2 ]; dp[2 ] = sum ; } return dp[2 ]; } };
746. 使用最小花费爬楼梯(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public: int minCostClimbingStairs(vector<int>& cost) { //思路:使用一维dp数组,dp表示跳到i层需要的最少花费 //dp可以由dp得到,此时的dp = dp + cost; //dp也可以由dp得到,此时的dp = dp + cost; //那么dp = min(dp + cost, dp + cost); //初始化dp数组:dp = 0; dp = 0; // 定义dp数组 vector<int> dp(cost.size() + 1); dp = 0; dp = 0; for(int i = 2;i <= cost.size();i++){ dp = min(dp + cost, dp + cost); } return dp; } };
746. 使用最小花费爬楼梯(C++动态规划实现,优化内存空间) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public: int minCostClimbingStairs(vector<int>& cost) { //优化空间复杂度 int dp; dp = 0; dp = 0; for(int i = 2;i <= cost.size();i++){ dp = min(dp + cost, dp + cost); dp = dp; dp = dp; } return dp; } };
62. 不同路径(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public: int uniquePaths(int m, int n) { //思路:设dp为动态数组,表示从(0, 0)开始到(i, j)总共有dp条路径 //而dp只能从两个方向来推导:dp和dp //初始化dp数组:从(0, 0)开始到(i, 0)或(0, j)的方法只有一个 //初始化dp数组 vector<vector<int>> dp(m, vector<int>(n, 0)); for(int i = 0;i < m; i++){ dp = 1; } for(int j = 0; j < n;j++){ dp = 1; } //遍历整个m*n网格 for(int i = 1;i < m;i++){ for(int j = 1;j < n;j++){ dp = dp + dp; } } return dp; } };
63. 不同路径 II(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution {public : int uniquePathsWithObstacles (vector<vector<int >>& obstacleGrid) { int m = obstacleGrid.size (); int n = obstacleGrid[0 ].size (); vector<vector<int >> dp (m, vector <int >(n, 0 )); for (int i = 0 ;i < m && obstacleGrid[i][0 ] == 0 ;i++){ dp[i][0 ] = 1 ; } for (int j = 0 ;j < n && obstacleGrid[0 ][j] == 0 ;j++){ dp[0 ][j] = 1 ; } for (int i = 1 ;i < m;i++){ for (int j = 1 ;j < n;j++){ if (obstacleGrid[i][j] == 1 ){ continue ; } dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ]; } } return dp[m - 1 ][n - 1 ]; } };
343. 整数拆分(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : int integerBreak (int n) { vector<int > dp (n + 1 ) ; dp[2 ] = 1 ; for (int i = 3 ;i <= n;i++){ for (int j = 1 ;j <= i / 2 ;j++){ dp[i] = max (dp[i], max (j * (i - j), j * dp[i - j])); } } return dp[n]; } };
96. 不同的二叉搜索树(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public: int numTrees(int n) { // 思路: // 节点数为1 的,只有一种; // 结点数为2 的,有两种; // 节点数为3 的,需要分情况讨论: // 1 .头节点为1 对应的种类数=右子树有2 个结点的种类数*左子树有0 个结点的种类数; // 2 .头节点为2 对应的种类数=右子树有1 个结点的种类数*左子树有1 个结点的种类数; // 3 .头结点为3 对应的种类数=右子树有0 个结点的种类数*左子树有2 个结点的种类数; // 那么节点数为3 对应的种类=头节点为1 对应的种类数+头节点为2 对应的种类数+头节点为3 对应的种类数 // 而:0 个结点的种类数为dp[0 ] = 1 ; // 有1 个结点的种类数为dp[1 ] = 2 ; // 有2 个节点的种类数为dp[2 ] = 2 ; // 那么得到递推公式为:dp[3 ] = dp[2 ] * dp[0 ] + dp[0 ] * dp[2 ] + dp[1 ] * dp[1 ]; // 定义初始化数组: vector<int> dp(n + 1 ); // 初始化dp[0 ]为1 ; dp[0 ] = 1 ; for (int i = 1 ; i <= n;i++){ for (int j = 1 ;j <= i;j++){ // j从1 开始遍历到i结束 // 更新dp动态数组 dp[i] += dp[j - 1 ] * dp[i - j]; } } return dp[n]; } };
01背包问题基础公式推导(C++动态规划实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution {public : void test_beibao_problem () { vector<int > weights = {1 , 3 , 4 }; vector<int > values = {15 , 20 , 30 }; int bagweight = 4 ; vector<vector<int >> dp (weights.size (), vector <int >(bagweight + 1 , 0 )); for (int j = weights[0 ];j <= bagweight;j++){ dp[0 ][j] = values[0 ]; } for (int i = 0 ;i < weights.size ();i++){ for (int j = 0 ;j <= bagweights;j++){ if (j < weights[i]){ dp[i][j] = dp[i - 1 ][j]; }else { dp[i][j] = max (dp[i - 1 ][j], dp[i - 1 ][j - weights[i]] + values[i]); } } } return dp[weights.size () - 1 ][bagweights]; } }
leetcode-notes-20230915
https://thewangyang.github.io/2023/09/15/leetcode-notes-20230915/