0%

贪心算法之简单题合集

455. 分发饼干

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

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

C++

class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(),s.end());
int res = 0; // 是g数组的下标,也是最终返回值
for(int i = 0; i < s.size(); i ++) {
if(res < g.size() && g[res] <= s[i]) res ++;
}
return res;
}
};

1005. K 次取反后最大化的数组和

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i]

重复这个过程恰好 k 次。可以多次选择同一个下标 i

以这种方式修改数组后,返回数组 可能的最大和

示例 1:

输入:nums = [4,2,3], k = 1
输出:5
解释:选择下标 1 ,nums 变为 [4,-2,3]

示例 2:

输入:nums = [3,-1,0,2], k = 3
输出:6
解释:选择下标 (1, 2, 2) ,nums 变为 [3,1,0,2]

C++

class Solution {
public:
int largestSumAfterKNegations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
while( k-- > 0) {
*nums.begin() = - *nums.begin();
sort(nums.begin(), nums.end());
}
int res = 0;
for(int e: nums) res += e;
return res;
}
};

860. 柠檬水找零

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

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

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

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

示例 :

输入:bills = [5,5,10,10,20]
输出:false
解释:
2 位顾客那里,我们按顺序收取 2 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

提示:

  • 1 <= bills.length <= 105
  • bills[i] 不是 5 就是 10 或是 20

C++

class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
vector<int> changes(2, 0); // 代表5块,10块个数
for(int e: bills){
if(e == 10){
changes[1] ++;
changes[0] --;
if(changes[0]<0) return false;
}
else if(e == 20){
if(changes[1] && changes[0]){ // 贪心体现在这,因为10块除了找付款20的零钱没有用,所以我们优先用它
changes[1] --;
changes[0] --;
}
else if(changes[0] >= 3) changes[0] -= 3;
else return false;
}
else changes[0] ++;
}
return true;
}
};