datawhale学习笔记(Leetcode基础算法202312):task04贪心算法

目录

贪心算法

贪心算法的定义

贪心算法的中心思想

贪心算法的不足

贪心算法的练习题

柠檬水找零问题

(1)问题描述

(2)输入输出示例

(3)解题思路

(4)代码实现

分发饼干问题

(1)问题描述

(2)输入输出示例

(3)解题思路

(4)代码实现

贪心算法

贪心算法的定义

贪心算法,也被称为贪婪算法,是一种寻找最优解问题的常用策略。这种算法的基本模式是将求解过程分成若干个步骤,在每个步骤中都应用贪心原则,选择当前状态下最好或最优的选择(局部最有利的选择),并期望通过这种方式能够产生全局最优解。

贪心算法的中心思想

贪心算法的基本思想是在问题的求解过程中,每一步都选择当前状态下最优(或最有利)的选择,寄希望于这样的局部最优解能推导出全局最优解。这种算法的实现步骤通常包括:首先建立问题的数学模型;然后将大问题分解为若干个子问题;接着对每一个子问题求解,得到子问题的局部最优解;最后将子问题的局部最优解合成原来问题的一个解。

贪心算法的不足

值得注意的是,贪心算法并不总是能够找到全局最优解,而是在许多情况下,它寻求的是某种意义上的局部最优解。此外,贪心算法的核心在于贪心策略的选择,该策略需要满足无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

贪心算法的练习题

柠檬水找零问题

(1)问题描述

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

(2)输入输出示例

示例 1:

输入:bills = [5,5,5,10,20]输出:true解释:前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。

第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。

第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。

由于所有客户都得到了正确的找零,所以我们输出 true。

示例 2:

输入:bills = [5,5,10,10,20]输出:false解释:

前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。

对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。

对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。

由于不是每位顾客都得到了正确的找零,所以答案是 false。

(3)解题思路

A.初始化两个变量 five 和 ten,分别表示5美元和10美元的数量。

B.遍历顾客支付的账单列表 bills。

C.如果顾客支付的是5美元,将 five 的值加1。

D.如果顾客支付的是10美元,首先检查是否有5美元的零钱,如果没有则返回False,否则将 five 的值减1,将 ten 的值加1。

E.如果顾客支付的是20美元,优先使用10美元和5美元的组合找零,如果没有10美元和5美元的组合,再尝试使用3个5美元找零。如果都无法找零,则返回False。

F.如果所有顾客都能顺利找零,最后返回True。

(4)代码实现
class Solution(object):

    def lemonadeChange(self, bills):

        five = ten = 0

        for bill in bills:

            if bill == 5:

                five += 1

            elif bill == 10:

                if not five: return False

                five -= 1

                ten += 1

            else:

                if ten and five:

                    ten -= 1

                    five -= 1

                elif five >= 3:

                    five -= 3

                else:

                    return False

        return True



        """

        :type bills: List[int]

        :rtype: bool

        """

分发饼干问题

(1)问题描述

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

(2)输入输出示例

示例 1:

输入: g = [1,2,3], s = [1,1]输出: 1解释:

你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。

虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子 满足。

所以你应该输出1。

示例 2:

输入: g = [1,2], s = [1,2,3]输出: 2解释:

你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。

你拥有的饼干数量和尺寸都足以让所有孩子满足。

所以你应该输出2.

(3)解题思路

首先对孩子的胃口值进行排序,然后遍历饼干尺寸,将满足条件的饼干分配给孩子。具体步骤如下:

A.对胃口值数组 g 进行升序排序。

B.初始化一个计数器 count 用于记录满足条件的孩子数量。

C.遍历饼干尺寸数组 s,对于每个饼干尺寸,检查是否有孩子可以满足这个饼干。如果有,将这个饼干分配给满足条件的孩子,并将孩子的胃口值从数组中移除。同时,将计数器 count 加1。

D.当所有的饼干都被分配完或者没有孩子可以满足时,结束循环。

E.返回计数器 count 的值,即满足条件的孩子数量。

 (4)代码实现
class Solution(object):

    def findContentChildren(self, g, s):

        g.sort()

        s.sort()

        child_i = cookie_j = 0

        while child_i < len(g) and cookie_j < len(s):

            if s[cookie_j] >= g[child_i]:

                child_i += 1

            cookie_j += 1

        return child_i



        """

        :type g: List[int]

        :type s: List[int]

        :rtype: int

        """

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值