14天阅读挑战赛——贪心算法(二)

14天阅读挑战赛

程序员面试最难的部分就是手写代码,手写代码测试不但能够考察算法运用能力,思维能力,还能看出代码编写习惯。
想去大厂,还是需要及早刷题,这次有机会参与读算法。
本节是书中的第二章,贪心算法。

图书试阅读地址
https://www.epubit.com/onlineEbookReader?id=fb652b37-b7a6-4843-a933-5ed68b2395c1

算法知识点

贪心的本质是选择每一阶段的局部最优,从而达到全局最优。

我一直觉得贪心和动态规划很像。其实通过看书、查资料,也得到一个规律,那就是贪心没有什么具体的公式。
如果找出局部最优并可以推出全局最优,就是贪心,如果局部最优都没找出来,就不是贪心,可能是单纯的模拟。

相关算法题型题目总结

贪心算法题目挺多,包括leetcode上面也有很多。我本身算法功底,数学功底还是偏弱,短时间内可能不适合看难题。本节就看一下中等难度的题目是怎么样的。

算法题目描述

leetcode-单调递增的数字

给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。

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

示例 1:

输入: N = 10
输出: 9
示例 2:

输入: N = 1234
输出: 1234
示例 3:

输入: N = 332
输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。

题目分析

作为一个小菜鸡程序员,看到题目内心os:就这还中等难度?不就是for循环的事嘛。
当然暴力解决肯定可以,就是不优雅。
运用贪心我们怎么做这个题目呢?

例如:98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]–,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。

这一点如果想清楚了,这道题就好办了。

局部最优:遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。

全局最优:得到小于等于N的最大单调递增的整数。

模板代码

class Solution {
public:
    int monotoneIncreasingDigits(int N) {
        string strNum = to_string(N);
        // flag用来标记赋值9从哪里开始
        // 设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
        int flag = strNum.size();
        for (int i = strNum.size() - 1; i > 0; i--) {
            if (strNum[i - 1] > strNum[i] ) {
                flag = i;
                strNum[i - 1]--;
            }
        }
        for (int i = flag; i < strNum.size(); i++) {
            strNum[i] = '9';
        }
        return stoi(strNum);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值