算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)

阅读完本文,你将对贪心算法有初步的认知和刷题能力。

贪心算法

用一句话概括:每一步都选局部最优解。

对于结果是不是最优解并不关心。因为对于全局来说,局部的每一步最优解累计起来,可能是最优解,也可能不是最优解。

因为贪心算法没有固定的模板,只是一种思想,所以本文收录了几道简单和中等难度的题目,用于认识和理解贪心算法。

贪心算法和贪吃蛇

我们用贪吃蛇的例子来感受贪心算法:

如果每一步都选择最优解,蓝色路线是贪心算法选出来的路线,而作为人类,我们一眼就能看出,红色路线是最优解。这个例子就是贪心算法不是最优解的例子。

Easy / 简单

Leetcode 121 - 买卖股票的最佳时机

Leetcode 121 - 买卖股票的最佳时机

首先来一道HOT100上贪心算法板块的简单题目。

本题的想法是,找最低的价格买入,找最高的价格卖出,求局部最优解,以获得全局最优解。

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        int minPrice = INT_MAX;
        int maxProfit = 0;
        for(int i = 0;i<n;i++){
            minPrice = min(minPrice,prices[i]);
            maxProfit = max(maxProfit,prices[i] - minPrice); 
        }
        return maxProfit;
    }
};

Leetcode 455 - 分发饼干

Leetcode 455 - 分发饼干

两列数据按照顺序排列后,注意越界判断,可以写在for循环里:

cpp 复制代码
 for (; ck < cookies.size() && cd < childs.size(); ck++)

也可以写在if里,但注意要在判断大小之前。如下:

cpp 复制代码
class Solution {
public:
    int findContentChildren(vector<int>& childs, vector<int>& cookies) {
        sort(cookies.begin(), cookies.end(), less<int>());
        sort(childs.begin(), childs.end(), less<int>());
        int ck = 0;
        int cd = 0;
        for( ;ck<cookies.size();ck++){
            if(cd <childs.size() && childs[cd] <= cookies[ck]){
                cd++;
            }
        }
        return cd;
    }
};

Leetcode 860 - 柠檬水找零

Leetcode 860 - 柠檬水找零

找零场景分为三种情况,顾客支付5,10,20 。5和10都比较简单,注意20时,当10的值为0时,考虑找零3张5 。

cpp 复制代码
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0;
        int ten = 0;
        for (int bill : bills) {
            if (bill == 5) {
                five++;
            } else if (bill == 10) {
                ten++;
                if (five) {
                    five--;
                } else {
                    return false;
                }
            } else {
                if (ten && five) {
                    ten--;
                    five--;
                } else if (five >= 3) {
                    five -= 3;
                } else {
                    return false;
                }
            }
        }
        return 1;
    }
}
;

Medium / 中等

Leetcode 376 摆动序列

cpp 复制代码
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        if(n<2){
            return n;
        }
        int preDiff = nums[1] - nums[0];
        int res = preDiff != 0? 2:1;
        for(int i = 2;i<n;i++){
            int diff = nums[i] - nums[i-1];
            if((diff > 0 && preDiff <=0)|| (diff < 0 && preDiff >=0)){
                res++;
                preDiff = diff;
            }
        }
        return res;
    }
};

Leetcode 738 - 单调增加的数字

首先尝试暴力法:

cpp 复制代码
class Solution {
public:
    bool isMono(int n){
        int pre = 10;
        while(n){
            int dig = n % 10;
            if(dig > pre) return false;
            pre = dig;
            n = n / 10;
        }
        return true;
    }
    int monotoneIncreasingDigits(int n) {
       while(n){
            if(isMono(n)){
                return n;
            }
            n--;
       } 
       return 0;
    }
};

发现不转换为字符串,是非常难解决的,尝试转换为字符串,例如85,最后结果是79,可以发现是if(si-1>si),需要把si-1--,且si=9。

再多举几个例子,例如8765,其中的过程是:8765->8759->8699->7999。故写出以下代码:

cpp 复制代码
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        for(int i = s.size()-1;i>0;i--){
            if(s[i-1]> s[i]){
                s[i-1]--;
                for(int j = i;j<s.size();j++) s[j] = '9';
            }
        }
        return stoi(s);
    }
};
相关推荐
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼1 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark1 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her11 天前
并查集-听课笔记
笔记·算法·并查集
码流子1 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven1 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark1 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218611 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法