代码随想录算法训练营第37天 || 738.单调递增的数字 || 总结

代码随想录算法训练营第37天 || 738.单调递增的数字 || 总结

738.单调递增的数字

题目介绍:

当且仅当每个相邻位数上的数字 xy 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

个人思路:

  • 一路遍历到出现递减处,然后在标记处-1,后面全改成9即可
  • 注意:其中可能出现相邻数字相等的情况,这时候标记数定在其第一个相同数,直到出现递增的下一个数标记点才移动。
class Solution {
    public int monotoneIncreasingDigits(int n) {
        //整体思路,一直遍历到单调递减处,然后修改递减处-1,然后后面全填9即可
        //注意,可能会出现35662,这类情况,所以所以我们得用一个标记修改位置,这个位置遇到相同数字就不移动
        char[] num = String.valueOf(n).toCharArray();
        int index = 0;
        for (int i = 0; i < num.length - 1; i++) {
            if (num[i] < num[i + 1])
                index = i + 1;
            else if (num[i] > num[i + 1]) {
                num[index++]--;
                while (index < num.length)
                    num[index++] = '9';
                break;
            }
        }
        return Integer.parseInt(String.valueOf(num));
    }
}

714.买卖彩票含手续费 和 968.监控二叉树 二刷再看

总结

贪心理论基础

  • 贪心无套路,可能是常识也可能不简单
  • 局部最优—>全局最优

贪心简单题

  • 贪心算法:分发饼干(opens new window)
    • 对两个数组进行排序,然后 双指针 从小开始逐个分配饼干即可
  • 贪心算法:K次取反后最大化的数组和(opens new window)
    • 按绝对值由大到小排序,然后遍历到负数就翻转,最后如果翻转次数有剩余,
    • 剩余次数为奇数就翻转最后一个数,偶数次则不管
  • 贪心算法:柠檬水找零
    • 找零的时候优先找大面额的,因为小面额的5元用途更多(可找5元、15元)

贪心中等题

  • 贪心算法:摆动序列(opens new window)
    • 先画出趋势图,然后观察构思
    • 发现可以保留极点值,中间的趋势点可删除(不用真删除,因为只统计个数)
    • 考虑平坡问题:
      • 上下坡中的平坡:保留其中一端的作为极值点,体现到代码中去一边 = 号
      • 单调平坡:不实时更新prediff,直到下一次单调的时候再修改
    • 首尾边界问题:推荐首尾设置成平坡,也可但不推荐写死,本题这样较麻烦
  • 贪心算法:单调递增的数字
    • 遍历到递减处停下,标记数-1,后面全改9
    • 注意:标记在相邻数相等时不移动

贪心解决股票问题

大家都知道股票系列问题是动规的专长,其实用贪心也可以解决

  • 贪心算法:买卖股票的最佳时机II(opens new window)
    • 法一:类似摆动序列画趋势图,然后找相邻极大极小值点即可
    • 法二:相邻的不断进行买卖,因为会抵消,遇到亏本就跳过
  • 贪心算法:买卖股票的最佳时机含手续费
    • 本题二刷再看,到时候用动态规划完成

两个维度权衡问题

在出现两个维度相互影响的情况时,两边一起考虑一定会顾此失彼,要先确定一个维度,再确定另一个一个维度。

  • 贪心算法:分发糖果(opens new window)
    • 两个维度,与左孩子相比还要和右孩子相比
    • 我们可以先正向满足一个维度,再逆向遍历满足另一个维度,二次遍历过程取二维度的结果中较大值
    • 注意:评分相等没有啥限制
  • 贪心算法:根据身高重建队列
    • 同样是两个维度都要考虑,我们先考虑身高,再考虑有多少个更高人排在前面
    • 本题不能反向考虑两个维度,因为先考虑k的条件,一个维度都无法确定
    • 局部最优:优先按身高 高的人的k来插入;全局最优:插入完毕后整个队列满足条件

贪心解决区间问题

  • 贪心算法:跳跃游戏(opens new window)
    • 本题通过遍历数组,控制for循环中能跳跃的最远距离,循环中不断刷新最远距离,在保证数据不越界的前提下,退出循环时看看next能不能到达数组最后一位即可。
  • 贪心算法:跳跃游戏II(opens new window)
    • 两个关键变量:当前可达最远距离下标、下一次可跳最远距离下标
    • for循环遍历,每次走完当前最远距离就跳到下一次下标,往返如此,记录次数(把握细节处理)
  • 贪心算法:用最少数量的箭引爆气球(opens new window)
    • 重叠区间收缩问题,先以左区间来排序二维数组
    • 标记最新右区间,比较当前结点的左区间和上一节点的右区间,重叠则缩小区间,不重叠则增加箭数,均更新标记的右区间
  • 贪心算法:无重叠区间(opens new window)
    • 依据左区间排序
    • 然后循环遍历排序后的数组,比较当前下标的左区间和上一个下标的右区间,看看是否有交集,有交集就保留右区间较小的那个(大概就是此处贪心,使得与后面的元素尽可能没有交集,这样得到移除数量最少的全局最优。
  • 贪心算法:划分字母区间(opens new window)
    • 先遍历一次,记录每个位置的字母最远相同字母所在位置
    • 二次遍历,用一个变量记录当前字母的最远相同字母下标,直到该位置算一个区间
  • 贪心算法:合并区间
    • 根据左区间进行排序
    • 然后比较当前节点的左区间与前一节点的右区间,符合条件则合并,不符继续遍历

你可能感兴趣的:(算法,贪心算法,leetcode)