c++入门99题61-70

解题报告

1.力扣剑指 Offer II 098. 路径的数目

原题链接

剑指 Offer II 098. 路径的数目

源码剖析

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

这题可以使用动态规划来解决,按照如下几个步骤:设计状态->写出状态转移方程->设定初始状态->执行状态转移->返回结果;

  • 设计状态:到达每一格的方案数即为状态 dp[i][j]
  • 写出状态转移方程:由于路径只允许向右或者向下,所以 当前格子的方案数=从上一格走来的方案数+从左一格走来的方案数字dp[i][j]=dp[i-1][j]+dp[i][j-1] 当然这是需要考虑到边界条件的。
  • 设定初始状态:第一格的方案 dp[0][0]1 ,同时到达第一行和第一列每一行的方案数也都是为 1 的。
  • 执行状态转移:见代码
  • 返回结果:由于数组的下标是从 0 开始的,因此最终需要的返回的第 mn 列的方案数应当是 dq[m-1][n-1]

2.力扣LCP 06. 拿硬币

原题链接

LCP 06. 拿硬币

源码剖析

class Solution {
public:
    int minCount(vector<int>& coins) {
        int ans = 0;
        for(int i = 0 ; i < coins.size() ; ++i) {
            ans += (coins[i]+1)/2;
        }
        return ans;
    }
};

不论一共有几个都可以直接用个数除以二然后向上取整。

3.力扣2278

原题链接

2278. 字母在字符串中的百分比

源码剖析

class Solution {
public:
    int percentageLetter(string s, char letter) {
        int i , len = s.size();
        int ans = 0;
        for(i = 0 ; i < len ; ++i){
            if(s[i] == letter){
                ans++;
            }
        }
        return 100*ans/len;
    }
};

注意变量要初始化。

4.力扣1018

原题链接

1018. 可被 5 整除的二进制前缀

源码剖析

class Solution {
public:
    vector<bool> prefixesDivBy5(vector<int>& nums) {
        vector<bool> ans; 
        int i = 0;
        int sum = 0;
        int len = nums.size();
        while(i < len) {
            sum<<=1;
            sum+=nums[i];
            sum%=5;
            i++;
            ans.push_back(!sum);
        }
        return ans;
    }
};

这里有一个小技巧, sum 在判断过程中不断的模除 5 就可以防止 sum 的值过大。

5.力扣剑指 Offer 10- I. 斐波那契数列

原题链接

剑指 Offer 10- I. 斐波那契数列

源码剖析

class Solution {
public:
    int fib(int n) {
        int dp[101] = {0};
        dp[1] = 1; 
        for(int i = 2;i<=n;++i){
            dp[i] = (dp[i-1] + dp[i-2])%1000000007;
        }
        return dp[n];
    }
};

这题如果直接使用递归是会超时的,可以使用动态规划来实现。

6.力扣509

原题链接

509. 斐波那契数

源码剖析

class Solution {
public:
    int fib(int n) {
        int dp[31] = {0};
        dp[1] = 1; 
        for(int i = 2;i<=n;++i){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
};

同上。

7.力扣剑指 Offer 10- II. 青蛙跳台阶问题

原题链接

剑指 Offer 10- II. 青蛙跳台阶问题

源码剖析

class Solution {
public:
    int numWays(int n) {
        int dp[101];
        dp[0] = 1;
        dp[1] = 1; 
        for(int i = 2;i<=n;++i){
            dp[i] = (dp[i-1] + dp[i-2])%1000000007;
        }
        return dp[n];
    }
};

同上,不过需要修改一下初始值。

8.力扣70

原题链接

70. 爬楼梯

源码剖析

class Solution {
    int dp[46];
public:
    int climbStairs(int n) {
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2 ; i <= n ; ++i){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
};

同上。

9.力扣剑指 Offer II 088. 爬楼梯的最少成本

原题链接

剑指 Offer II 088. 爬楼梯的最少成本

源码剖析

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int dp[1001];
        dp[0] = 0;
        dp[1] = 0;
        int n = cost.size();
        for(int i = 2 ; i <= n; ++i){
            dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }
};

这题一定要理清楚初始状态,然后到达当前层数的可能性就只有两种了,要不然就是爬了一格到当前层,要不然就是爬两层到当前层,然后取这两者中最少的就是到达当前楼层的最少花费。是一个最基础的动态规划。

10.力扣746

原题链接

746. 使用最小花费爬楼梯

源码剖析

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int dp[1001];
        dp[0] = 0;
        dp[1] = 0;
        int n = cost.size();
        for(int i = 2 ; i <= n; ++i){
            dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }
};

同上。

你可能感兴趣的:(c++入门99例,c++,leetcode,算法)