动态规划笔记
来源:互联网 发布:自学 java c python 编辑:程序博客网 时间:2024/06/06 09:18
283. Move Zeroes
27. Remove Element
26. Remove Duplicates from Sorted Array
80. Remove Duplicates from Sorted Array II
283. Move Zeroes
// 解法一:最直观的解法,新建一个vector res,遍历nums,将非0元素依次赋值入res即可// 时间复杂度O(n),空间复杂度O(n)class Solution {public: void moveZeroes(vector<int>& nums) { vector<int> res(nums.size(), 0); int index = 0; for(auto it = nums.begin(); it != nums.end(); ++it){ if(*it != 0){ res[index] = *it; ++index; } } nums = res; }};
动态规划
70.Climbing Stairs
// 解法一:递归class Solution {public: int climbStairs(int n) { if( n == 0 || n == 1) return 1; return climbStairs(n-1) + climbStairs(n-2); }};
// 解法二:递归+记忆化搜索class Solution {private: vector<int> memo; int calcWays(int n){ if(n == 0 || n == 1) return 1; if(memo[n] == -1){ memo[n] = calcWays(n-1) + calcWays(n-2); } return memo[n]; }public: int climbStairs(int n) { memo = vector<int>(n+1, -1); return calcWays(n); }};
// 解法三:动态规划class Solution {public: int climbStairs(int n) { // n >= 1 vector<int> memo(n+1, -1); memo[0] = 1; memo[1] = 1; for( int i = 2 ; i <= n ; i ++ ) memo[i] = memo[i-1] + memo[i-2]; return memo[n]; }};
120. Triangle
// 自上向下class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { vector<vector<int>> res(triangle.size(), vector<int>(triangle.size(), -1)); for(int i = 0; i < triangle.size(); ++i){ for(int j = 0; j < triangle[i].size(); ++j){ if(i == 0) res[i][j] = triangle[i][j]; else if(j == 0) res[i][j] = res[i-1][j] + triangle[i][j]; else if(j >= triangle[i-1].size()) res[i][j] = res[i-1][j-1] + triangle[i][j]; else res[i][j] = min(res[i-1][j-1], res[i-1][j]) + triangle[i][j]; } } return *min_element(res[triangle.size()-1].begin(), res[triangle.size()-1].end()); }};
64. Minimum Path Sum
// 创建一个和输入矩阵同等大小的矩阵res// res[row][col]存储从左上角到达这个点的最小距离// res[row][col] = min(grid[row-1][col], grid[row][col-1]) + grid[row][col]class Solution {public: int minPathSum(vector<vector<int>>& grid) { if(grid.size() == 0) return 0; vector<vector<int>> res(grid.size(), vector<int>(grid[0].size(), -1)); for(int row = 0; row < grid.size(); ++row){ for(int col = 0; col < grid[0].size(); ++col){ // min(grid[row-1][col], grid[row][col-1]) + grid[row][col] // 处于第一行,第一列 if(row == 0 && col == 0){ res[row][col] = grid[row][col]; } // 第一行,没有上侧元素 else if(row == 0){ res[row][col] = res[row][col-1] + grid[row][col]; } // 第一列,没有左侧元素 else if(col == 0){ res[row][col] = res[row-1][col] + grid[row][col]; } else{ res[row][col] = min(res[row-1][col], res[row][col-1]) + grid[row][col]; } } } return res[grid.size() - 1][grid[0].size() - 1]; }};
343. Integer Break
// n = 1 n = 2 n = 3比较特殊,单独考虑// n >= 4 : f(n) = max(f(n-1)*f(1), f(n-2)*f(2),...,f(1)*f(n-1))// f(n-1)f(1) 与 f(1)f(n-1)重复计算,算一半就可以了,循环条件j <= i/2即可class Solution {public: int integerBreak(int n) { if(n == 2) return 1; if(n == 3) return 2; // n >= 4 vector<int> res(n+1, -1); res[1] = 1; // n = 1 res[2] = 2; // n = 2 res[3] = 3; // n = 3 for(int i = 4; i <= n; ++i){ int temp = 0; for(int j = 1; j <= i/2; ++j){ temp = max(temp, res[j] * res[i-j]); } res[i] = temp; } return res[n]; }};
279. Perfect Squares
// 简单的动态规划思想,但leetcode超时了class Solution {public: int numSquares(int n) { if(n < 1) return 0; vector<int> res(n+1, 0); res[0] = 0; res[1] = 1; for(int i = 2; i <= n; ++i){ // n本身就是一个完全平方数,不需要拆开,结果直接置为1 if(int(sqrt(i)) * int(sqrt(i)) == i) res[i] = 1; else{ int min_count = INT_MAX; // 需要拆成两个数 for(int j = 1; j <= i/2; ++j){ min_count = min(res[j]+res[i-j], min_count); } res[i] = min_count; } } return res[n]; }};
// 改进一下:// 通过leetcodeclass Solution {public: /* 如果一个数x可以表示为一个任意数a加上一个平方数bxb,也就是x = a + bxb, * 那么能组成这个数x最少的平方数个数,就是能组成a最少的平方数个数加上1(因为b*b已经是平方数了)。 */ int numSquares(int n) { // 将所有非平方数的结果置最大,保证之后比较的时候不被选中 vector<int> nums(n + 1, INT_MAX); // 将所有整平方数的结果置1 for (int i = 0; i*i <= n; ++i) nums[i*i] = 1; // 从小到大找任意数a for (int a = 0; a <= n; ++a){ // 从小到大找平方数b*b for (int b = 0; a + b*b <= n; ++b){ // 因为a+b*b可能本身就是平方数,所以我们要取两个中较小的 nums[a + b*b] = min(nums[a] + 1, nums[a + b*b]); } } return nums[n]; }};
91. Decode Ways
// 和青蛙跳台阶很像// f(n) = f(n-1) + f(n-2)// 但是多了限制条件,需要检查最后一个或两个数字是否能构成有效的编码class Solution {public: int numDecodings(string s) { if (s.empty()) return 0; vector<int> res(s.size() + 1, 0); if (s.size() >= 1 && isValidForOneBit(int(s[0] - '0'))) res[1] = 1; if (s.size() >= 2){ if (isValidForOneBit(s[0] - '0') && isValidForOneBit(int(s[1] - '0'))) res[2] += 1; if (isValidForTwoBit(atoi(s.substr(0, 2).c_str()))) res[2] += 1; } for (int i = 2; i < s.size(); ++i){ if (isValidForOneBit(int(s[i] - '0'))) res[i + 1] += res[i]; if (isValidForTwoBit(atoi(s.substr(i - 1, 2).c_str()))) res[i + 1] += res[i - 1]; } return res[s.size()]; } bool isValidForOneBit(int n){ return n >= 1 && n <= 9; } bool isValidForTwoBit(int n){ return n >= 10 && n <= 26; }};
62. Unique Paths
// 这题动态规划就很简单了// res[row][col] += res[row-1][col] + res[row][col-1]// 注意边界条件即可class Solution {public: int uniquePaths(int m, int n) { if(m <= 0 || n <= 0) return 0; vector<vector<int>> res(m, vector<int>(n, 0)); for(int i = 0; i < n; ++i) res[0][i] = 1; for(int i = 0; i < m; ++i) res[i][0] = 1; for(int row = 1; row < m; ++row){ for(int col = 1; col < n; ++col) res[row][col] += res[row-1][col] + res[row][col-1]; } return res[m-1][n-1]; }};
63. Unique Paths II
// 相比上一题,多了一点点限制条件而已class Solution {public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { if(obstacleGrid.size() <= 0 || obstacleGrid[0].size() <= 0) return 0; vector<vector<int>> res(obstacleGrid.size(), vector<int>(obstacleGrid[0].size(), 0)); if(obstacleGrid[0][0] == 1) return 0; res[0][0] = 1; // 第一行 for(int col = 1; col < obstacleGrid[0].size(); ++col){ if(obstacleGrid[0][col] != 1) res[0][col] = res[0][col-1]; else res[0][col] = 0; } // 第一列 for(int row = 1; row < obstacleGrid.size(); ++row){ if(obstacleGrid[row][0] != 1) res[row][0] = res[row-1][0]; else res[row][0] = 0; } // 其他 for(int row = 1; row < obstacleGrid.size(); ++row){ for(int col = 1; col < obstacleGrid[0].size(); ++col) if(obstacleGrid[row][col] != 1) res[row][col] += res[row-1][col] + res[row][col-1]; else res[row][col] = 0; } return res[obstacleGrid.size()-1][obstacleGrid[0].size()-1]; }};
198. House Robber
213. House Robber II
337. House Robber III
309. Best Time to Buy and Sell Stock with Cooldown
阅读全文
1 0
- 动态规划学习笔记
- 动态规划学习笔记
- 动态规划学习笔记
- 动态规划笔记
- 动态规划算法笔记
- 动态规划--学习笔记
- ACM 动态规划笔记
- 【算法】动态规划笔记
- 动态规划学习笔记
- 动态规划笔记
- 动态规划-入门笔记
- 学习笔记---动态规划
- 动态规划简要笔记
- 动态规划学习笔记
- 动态规划学习笔记
- 动态规划笔记
- 【笔记】动态规划w
- 动态规划学习笔记
- 简单梳理一下Android中MVP设计思想,个人学习用
- hrbust 1492 盒子 (二分图匹配)
- ORACLE Linux 平台下 误删 oracle 数据文件的恢复方法
- Java 序列化Serializable详解(附详细例子)
- 执行 webpack-dev-server –content-base src –hot –inline 出错
- 动态规划笔记
- sqlite3 数据库封装 (聊天室用的)
- Javacript陷阱
- 网络模型--Densely Connected Convolutional Networks
- 链表逆置
- 07 在ZStack里创建自己的task
- ButterKnife 添加使用
- nova 组件详解,schedule是怎么调度的
- 1130: 杨辉三角