leetcode-zgd-day37-738.单调递增的数字/714.买卖股票的最佳时机含手续费/968.监控二叉树

101 阅读2分钟

738.单调递增的数字

题目链接:Loading Question... - 力扣(LeetCode)

解题思路:

先将数字转换成字符串再转换成char数组,然后再进行处理,最后将char数组在转换回数字

创建一个samestart用于存储出现相等连续数字的时候的变更位置

没出现重复数字的情况下直接使用便利的下标i即可。

 class Solution {
     public int monotoneIncreasingDigits(int n) {
         if(n >=0 && n <= 9) return n;
         //432   399   452  449 410  399
         // 思路:找到第一个不符合条件的数字,将他本身以及后面的所有数字变为9,前一位数字减1
         char[] record = Integer.toString(n).toCharArray();
         int j = -1;
         int samestart = -1; // 用于记录连续重复数字中的第一个下标
         for(int i = 1; i < record.length; i++){
             if(record[i] == record[i - 1] && samestart == -1){ // 有重复的记录第一个
                 samestart = i;
             }
             else if(record[i] < record[i - 1]){
                 if(samestart == -1){
                     j = i;
                     record[j - 1]--;
                 }else{
                     j = samestart;
                     record[j - 1]--;
                 }
                 break;
             }
             else if(record[i] > record[i - 1]){
                 samestart = -1;
             }
         }
         if(j == -1) return n;
         for(int i = j; i < record.length; i++){
             record[i] = '9';
         }
         System.out.println(Integer.valueOf(new String(record)));
         return Integer.valueOf(new String(record));
     }
 }

714.买卖股票的最佳时机含手续费

题目链接:Loading Question... - 力扣(LeetCode)

解题思路:

其实最重要的一个点就是如何处理好手续费的问题,当股票一直涨或者下跌没超过手续费的时候,不会将股票频繁卖出,肯定是等股票涨不动了才卖。这种时候可以通过提前在minPrice中扣减手续费fee的方式来模拟一个中间交易过程没有手续费的情况。也就是说在股票一直涨的时候中间可以一直结算利润,不过不扣除手续费,只有在最后一次真正卖出这个股票完成交易的时候才扣除手续费。

 class Solution {
     public int maxProfit(int[] prices, int fee) {
         int sum = 0;
         // 遍历这个数组,维护一个startPrice
         int minPrice = prices[0];
         for(int i = 1; i < prices.length; i++){
             // 在这里买入
             if(minPrice > prices[i]) minPrice = prices[i];
             // 什么也不做,在这里卖出入不敷出,有手续费,不买入不卖出
             if(minPrice <= prices[i] && prices[i] <= minPrice + fee){
                 continue;
             }
             // 卖出!但是这里的卖出是一个相对含义,并非一定真正的卖出了,还要看后面这个股票会不会继续涨
             if(prices[i] > minPrice + fee){
                 sum += prices[i] - minPrice - fee;
                 // 这里对minPrice进行一个手续费的扣减,在股票一直涨的情况下模拟没有手续费的买卖场景。
                 minPrice = prices[i] - fee; // 只有最后的最大值卖出点不使用这个minPrice,在最后才扣除这个手续费。
             }
         }
         return sum;
     }
 }

968.监控二叉树

题目链接:968. 监控二叉树 - 力扣(LeetCode)

解题思路:

这个题需要思考的点:

二叉树的遍历方式,为什么要自底向上进行遍历:因为根据贪心算法,叶子节点肯定不要装摄像头。所以要自底向上,先考虑叶子节点

如何能够实现隔一个一个摄像头:采用状态转移的方式,标记每个结点的状态,根据状态计算摄像头个数

为什么要单独考虑最后的跟节点:因为根节点可能存在左孩子和右孩子都被覆盖的情况。这种情况在其他节点上面都只会直接标记一个未覆盖,并让未覆盖的父节点装摄像头,但是根节点没有父节点了,所以需要单独考虑。

 class Solution {
     int ans = 0;
 ​
 ​
     public int minCame(TreeNode root){
         if(root == null) return 2;
         int left = minCame(root.left);
         int right = minCame(root.right);
         if(left == 2 && right == 2) return 0; // 左右都有覆盖,当前root一定无覆盖
         if(left == 0 || right == 0){
             ans++; // root需要安装摄像头 数量加1
             return 1; // 返回安装摄像头状态
         }
         else return 2;
     }
 ​
     public int minCameraCover(TreeNode root) {
         // 递归的方法解题
         if(minCame(root) == 0){
             ans++;
         }
         return ans;
     }
 }