• 代码随想录训练营第37天|LeetCode 738.单调递增的数字、714. 买卖股票的最佳时机含手续费、 968.监控二叉树


    参考

    代码随想录

    题目一:LeetCode 738.单调递增的数字

    找规律:
    100 —> 99
    332 —> 299
    98 —> 89
    10 —> 9
    得到的数都有一个特点,以9结尾,不难理解,这样才能保证这个数最大。
    对于数字n,如果第i位比第i+1位大,那么应该将第i位减1,第i+1位变成9,这是局部的变化方法,而整体应该从后往前遍历,因为如果从前往后遍历,那么第i为减1之后就很可能导致比第i-1位还小(例如如果从前往后遍历,332得到的是329,显然不对),因此要从后往前遍历。代码实现如下:

    class Solution {
    public:
        int monotoneIncreasingDigits(int n) {
            string strNum = to_string(n);
            int index = strNum.size();
            for(int i = strNum.size()-1; i > 0; i--){
                if(strNum[i] < strNum[i-1]){
                    index = i;
                    strNum[i - 1] --;
                }
            }
            for(int i = index; i < strNum.size(); i++)
                strNum[i] = '9';
            return stoi(strNum);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    题目二:LeetCode 714.买卖股票的最佳时机含手续费

    本题相对于贪心算法:122.买卖股票的最佳时机II ,多添加了一个条件就是手续费。
    如果没有手续费,就将利润分解,然后只关心正利润,这相当于在极小值点处买入,在极大值点处卖出,然而现在有了手续费,就不能再任意极大值点卖出了,要综合考虑利润和手续费。
    如果使用贪心策略,就是最低值买,最高值(如果算上手续费还盈利)就卖。

    此时无非就是要找到两个点,买入日期,和卖出日期。

    • 买入日期:其实很好想,遇到更低点就记录一下。
    • 卖出日期:这个就不好算了,但也没有必要算出准确的卖出日期,只要当前价格大于(最低价格+手续费),就可以收获利润,至于准确的卖出日期,就是连续收获利润区间里的最后一天(并不需要计算是具体哪一天)。
      所以我们在做收获利润操作的时候其实有三种情况:

    情况一:收获利润的这一天并不是收获利润区间里的最后一天(不是真正的卖出,相当于持有股票),所以后面要继续收获利润。
    情况二:前一天是收获利润区间里的最后一天(相当于真正的卖出了),今天要重新记录最小价格了。
    情况三:不作操作,保持原有状态(买入,卖出,不买不卖)

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int result = 0;
            int minPrice = prices[0]; // 记录最低价格
            for (int i = 1; i < prices.size(); i++) {
                // 情况二:相当于买入
                if (prices[i] < minPrice) minPrice = prices[i];
    
                // 情况三:保持原有状态(因为此时买则不便宜,卖则亏本)
                if (prices[i] >= minPrice && prices[i] <= minPrice + fee) {
                    continue;
                }
    
                // 计算利润,可能有多次计算利润,最后一次计算利润才是真正意义的卖出
                if (prices[i] > minPrice + fee) {
                    result += prices[i] - minPrice - fee;
                    minPrice = prices[i] - fee; // 情况一,这一步很关键
                }
            }
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    Ubuntu18.04系统安装并配置redis
    IIC总线专题超级全
    MYSQL表的连接方式
    【JavaScript】leetcode链表相关题解
    条码工具 Dynamic Web TWAIN HTML5 版本的工作原理
    redis缓存穿透问题及解决方案代码实现
    修改element-UI组件样式
    常用SQL语句大全
    【算法】深入了解数据压缩算法(无损压缩和有损压缩)
    两分钟打造一个转属于你的网址导航(零基础,告别广告困扰)
  • 原文地址:https://blog.csdn.net/qq_70244454/article/details/128132007