算法入门(六):贪心算法 - 基础入门(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);
    }
};
相关推荐
OPEN-F1 小时前
C++11/14新特性精讲:移动语义与智能指针实战
开发语言·c++·算法
lisin-lee-cooper1 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法
sunburn-1 小时前
Java堆(Heap)详解与实战教学
java·开发语言·数据结构·ide·算法
智碳能碳管理平台2 小时前
工业能耗台账标准化:能碳管理系统的数据口径怎么设计
算法·能碳管理系统·智碳能碳管理平台·企业能碳管理系统·碳排放核算软件·绿色工厂申报saas·能碳管理平台
带多刺的玫瑰3 小时前
Leecode#15刷题之三数之和
算法·leetcode·职场和发展
圣保罗的大教堂3 小时前
leetcode 877. 石子游戏 中等
leetcode
哭泣方源炼蛊3 小时前
并查集进阶 P1(带权并查集,并查集分类)
数据结构·c++·算法·二进制·带权并查集
牧羊人.3333 小时前
动手学深度学习 02 | 手写数字识别
图像处理·人工智能·深度学习·算法
武帝为此3 小时前
【InnoDB存储引擎介绍】
数据库·算法
shehuiyuelaiyuehao4 小时前
算法32,连续数组,前缀和+哈希表
算法·leetcode·职场和发展