day31 代码随想录 | 单调递增的数字 和 贪心总结

738.单调递增的数字

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

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

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

这个题其实很简单,用贪心思路,如果遇到不是递增的,我们把这位置变成9,前面一位减去1。

只不过这个题你要看遍历顺序。

一种常规的思路就是,我从后往前遍历。如果遇到不是递增的,我把当前不是递增及其后面的元素全部变成9,前面一位的数字减去1。就可以了,这个思路是简洁的,也是大部分参考答案的版本,代码如下。

def monotoneIncreasingDigits(self, n: int) -> int:
    str_list = list(str(int))

    for i in range(len(str_list)-1, 0, -1):
        if str_list[i-1] > str_list[i]:
            str_list[i-1] = str(int(str_list[i-1]) -1)
            str_list[i:] = "9" * (len(str_list) - i )
    
    return int("".join(strNum))

在没看参看答案之前,我自己也做出来,但思路有一点不一样。我是先从左向右遍历。如果他是递增,那我直接返回;如果发现有元素不是递增,我记录这个不是递增的index,我记录为break_point, 并中止遍历。

那么在break_point及其以后的数字都应该赋值为9

那么接下来我就该处理[0, break_point-1]这个区间的元素。

我在这里已经找到[0, break_point-1]这个数字肯定是非递减的,但是可能存在重复元素,比如122

我们从右向左遍历,如果发现 后一个元素大于前一个元素,那么我们可以直接在后一个元素减去1,然后直接跳出循环;但是如果后一个元素等于前一个元素,那就又得分情况考虑。如果前一个元素不是队首元素,那么我们得让后一个元素变成9【因为你们相等 你减去1 那么于前面得冲突了】,索引继续移动;如果是队首元素,我们是让队首元素减去1。

def monotoneIncreasingDigits(n: int) -> int:
    str_n = list(str(n))
    if len(str_n) <= 1:
        return n
    flag = True
    break_index = 0
    for i in range(1, len(str_n)):
        if str_n[i] < str_n[i-1]:
            flag = False
            break_index = i
            break
    
    if flag:
        return n
    else:
        # 断点之后的都应该为9 这没问题
        for i in range(break_index, len(str_n)):
            str_n[i] = '9'
        # 那么就要操作前面了
        # 涉及到首位的问题
        # if len(str_n) - break_index < 2:
        #     str_n[0] = str(int(str_n[0])-1)
        #     return int(''.join(str_n))
        if break_index -2 < 0:
            str_n[0] = str(int(str_n[0])-1)
            return int(''.join(str_n))


        for i in range(break_index-2, -1, -1):
            # 从break_point开始的 说明钱买你是非递减 如果一来就直接 i < i+1了 那就可以结束了 因为i+1肯定是可以减去1的
            if str_n[i] < str_n[i+1]:
                str_n[i+1] = str(int(str_n[i+1])-1)
                break
            elif str_n[i] == str_n[i+1] and i !=0:
                str_n[i+1] = '9'
            elif str_n[i] == str_n[i+1] and i == 0:
                str_n[i+1] = '9'
                str_n[i] = str(int(str_n[i])-1)
            else:
                break   


        return int(''.join(str_n))

贪心总结

感觉就是没有规律。有些简单得贪心你很容易想到思路

有些是就是想不到。

多练习 多刷

特别是最大子序和

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值