什么是贪心算法
贪心算法的本质是有局部最优解推出全局最优解。
我们可以从最简单的习题来逐步分析了解
题型训练
分发饼干
力扣题目链接
题目
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j]>= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是满足尽可能多的孩子,并输出这个最大数值。
分析题意
我们用饼干1,3,5,9去满足小孩的胃1,2,7,10
为了实现利益最大化,我们肯定是要将大饼干去满足大胃口的小孩,9–7,5–2,1–1。
1.将饼干和胃按从小到大顺序排
2.用饼干去满足胃
代码实现
sort(g.begin(), g.end());//将饼干排序
sort(s.begin(), s.end());//将胃排序
int index = s.size() - 1; // 饼干数组的下标
int result = 0;
for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口
if (index >= 0 && s[index] >= g[i]) { // 遍历饼干
result++;
index--;
}
}
return result;
最大子序和
力扣题目链接
题目
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
分析
本文讲贪心,所以我们就只先用贪心来解该题
想:什么时候会拉低总和? 负数!!
所以我们要避免在每加一个数时,不让他变为负数。
代码实现时,当sum总和变为负数,直接将sum归为0,重新遍历,用ans记录最大子序列的和。
代码实现
int sum=0;
int ans=-10000;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i];//
ans=max(sum,ans);//记录最大和
if(sum<0)
{
sum=0;//变负数置为零
}
}
return ans;
跳跃游戏
力扣题目链接
题目
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
分析
判断是否可以走到终点,我们可以在每次跳跃步数时选取最大值即可。
根据样例:
先选2步数,当走到3时,剩余步数为1,将跳跃步数更新为更大步数3继续前进。
当走到1时,剩余步数为2较大,继续以剩余步数跳跃到1,最后再跳跃一步到4。
用t来记录跳跃剩余步数
代码实现
int t=-1000;
if(nums[0]==0&&nums.size()==1) return true;//如果数组只有一位0,返回true
for(int i=0;i<nums.size();i++)
{
t=max(t,nums[i]);//更新最大步数
if(t==0&&i!=nums.size()-1) return false;//步数不足到达最后的位置
else
t--;
}
return true;
章尾
本篇文章就到这里啦,有想在此基础上继续讨论一些贪心算法的题目的,请往这边来贪心算法–进阶