70-爬楼梯
思路:该问题可以理解为经典的“斐波那契数列”问题,但这里需要用动规实现,递归会超时
class Solution { public: int climbStairs(int n) { vector<int> memo(n+1,-1); memo[0]=memo[1]=1; for (int i=2;i<=n;i++) memo[i]=memo[i-1]+memo[i-2]; return memo[n]; } };
120-三角形最小路径和
思路:可以考虑从三角形的最后一行作为更新的数组,然后逐步向上遍历出最小的元素放在第一位,第一位即为所求。
class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { vector<int> dp(triangle.back()); for(int i=triangle.size()-2;i>=0;i--){ for(int j=0;j<=i;j++){ dp[j]=min(dp[j],dp[j+1])+triangle[i][j]; } } return dp[0]; } };
64-最小路径和
思路:基础动规,比较上面[i-1][j]和左边[i][j-1]的大小,然后当前值相加最小值,求和
class Solution { public: int minPathSum(vector<vector<int>>& grid) { if(grid.empty()||grid[0].empty()) return 0; for(int i=0;i<grid.size();i++){ for(int j=0;j<grid[0].size();j++){ if(i==0&&j==0) continue; if(i==0) grid[0][j]+=grid[0][j-1]; else if(j==0) grid[i][0]+=grid[i-1][0]; else grid[i][j]+=min(grid[i-1][j],grid[i][j-1]); } } return grid.back().back(); } };
343-整数拆分
思路:用一个一维数组存储拆分后的乘积,动态规划遍历拆分的2个数的最大乘积。
279-完全平方数
思路:动规过程中,dp的下标i从0循环到n,j从1循环到 i+j*j <= n 的位置,然后每次更新 dp[i+j*j] 的值,动态更新 dp 数组
class Solution { public: int numSquares(int n) { vector<int> dp(n+1,INT_MAX); dp[0]=0; for(int i=0;i<=n;i++){ for(int j=1;i+j*j<=n;j++){ dp[i+j*j]=min(dp[i+j*j],dp[i]+1); } } return dp.back(); } };
91-解码方法
思路:在遍历过程中判断先判断每个数字是否为0,若是则将dp[i]赋为0,否则赋上dp[i-1]的值。然后观看数组是否存在。如果存在且满足前一位是1,或者和当前位一起组成的两位数不大于26,则当前dp[i]的值加上dp[i-2]的值。最终返回dp数组的最后一个值即可。
class Solution { public: int numDecodings(string s) { if (s.empty() || s[0] == '0') return 0; vector<int> dp(s.size() + 1, 0); dp[0] = 1; for (int i = 1; i < dp.size(); ++i) { dp[i] = (s[i - 1] == '0') ? 0 : dp[i - 1]; if (i > 1 && (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6'))) { dp[i] += dp[i - 2]; } } return dp.back(); } };