顾名思义,贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的。
注:以下问题引入是GitHub某位大佬的著作里面的原话,这里仅供各位学习。本书永久免费地址:github.com/changgyhub/leetcode_101 。
分配问题
区间问题
做题记录
leetcode605:种花问题(难度:简单)
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。
示例 1:
输入:flowerbed = [1,0,0,0,1], n = 1
输出:true
示例 2:
输入:flowerbed = [1,0,0,0,1], n = 2
输出:false
第一次提交受书中分糖题目的影响(题目中用vector类,采用顺序和逆序两次遍历),当时没有看到两个题目之间的区别,竟也使用了两次遍历(当时一定是脑抽了,其实这题一次遍历就可以)。
当时第一次提交的错误答案:
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int count=0;
for(int i=0; i<flowerbed.length; i++){
if(flowerbed[i]==1){
break;
}else{
if(i>=1&&flowerbed[i-1]==1){
break;
}else{
flowerbed[i]=1;
count++;
}
}
}
for(int j=flowerbed.length-1; j>=0; j--){
if(flowerbed[j]==0){
break;
}else{
if(j<flowerbed.length-2&&flowerbed[j+1]==1){
flowerbed[j]=0;
count--;
}else{
break;
}
}
}
if(count<=n){
return true;
}
return false;
}
}
其实这里我觉得理论上是可以的,不知道为什么测试结果不太正确,而且这里的两次遍历完全是多此一举,后来看到了别人的解题思路,修改后提交:
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
for(int i=0; i<flowerbed.length; i++){
if(flowerbed[i]==1){
i++;
}else if(flowerbed[i]==0&&(i+1==flowerbed.length||flowerbed[i+1]==0)){
n--;
i++;
}
}
return n<=0;
}
}
这里的算法思想是:从头到尾遍历一次,如果是1,则直接跳过下一个遍历,因为后两个才有可以种花的可能。如果是0,则证明前一个肯定是0,因为前一个如果是1的话可能不会遍历后一个,所以我们这里只需要再判断一下后面一个是0的话就可以种花啦。这里注意一下细节问题:如果遍历到最后一个元素,则i+1个元素是不存在的,则直接种花就可以啦。
leetcode122 买卖股票的最佳时机(难度:中等)
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
示例 2:
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
做题耗时25分钟。其实思路很快就有了,但可能基础不太好,写代码过程中对一些条件语句的思考耗时比较长,而且测试用例错误,加上修修改改,,自然耗时比较长了。提交了一次就通过了,相比之前还是有进步的。
class Solution {
public int maxProfit(int[] prices) {
int profit=0;
int buy=0;
int sell=0;
while(sell<prices.length){
if(prices[sell]<=prices[buy]){
buy=sell;
}else{
if(sell+1==prices.length || prices[sell+1]<prices[sell]){
profit = prices[sell]-prices[buy]+profit;
buy = sell;
}
}
sell++;
}
return profit;
}
}
提交结果:
算法思路:设定两个指针buy(买入)和sell(卖出),再设置总利润profit。遍历一遍数组,当prices[sell]比prices[buy]低时,则不会卖出,否则亏本,这时经较低价格的price[sell]赋值给买入;当prices[sell]比prices[buy]高时,再判断prices[sell+1]是否更高,更高则不宜卖出,当prices[sell+1]<peices[sell]则卖出,每次卖出的价格都累计到profit中。这里再注意一下当遍历到结尾的情况,此时不存在sell+1。