题目链接:860. 柠檬水找零 - 力扣(LeetCode)
这道题我们只要顺序按照数组判断是否能有钱找零即可,我们定义三个变量来记录每张钞票目前的数量,其中我们知道给10元得找5元,给二十元得找515元,而15元的组合有10元+5元和3个5元构成,这里我们知道5元的通用性更强,而十元只能用于20元的找零,所以对于前面我们都正常操作,而对20元我们优先花掉十元的再去考虑5元的情况,最后考虑三张5元的情况.
局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。
class Solution {
public boolean lemonadeChange(int[] bills) {
int coin_5 = 0;
int coin_10 = 0;
int coin_20 = 0;
for(int bill:bills)
{
if(bill == 5)
{
coin_5++;
}
if(bill == 10)
{
if(coin_5 <=0)
{
return false;
}
coin_10++;
coin_5--;
}
if(bill == 20)
{
if(coin_10>0 && coin_5>0)
{
coin_10--;
coin_5--;
}else if(coin_5>=3)
{
coin_5-=3;
}
else
{
return false;
}
}
}
return true;
}
}
题目链接:406. 根据身高重建队列 - 力扣(LeetCode)
这题的思路和昨天的那个分发糖果问题类似,都是从两个维度讨论问题,昨天是从左右两边来考虑问题,这题我们仍然要从两个角度考虑问题,但是一定不要同时考虑两个角度,而是一个一个来避免顾此失彼,我们可以尝试一下,按照k值排序,发现排序完我们得不到想要的结果,那我们再按照升高来排序,这样我们就确定了一点,排在某个人前面的一定是身高大于等于他的,这样我们就只需要再考虑前面有多少个人即可.
下面我们就只需要考虑将每个人安排前面有几个人的身高大于等于他就行了,我们开始操作,其实就是将ki的大小作为下标,直接插入即可.
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people,(a,b)-> //lambda表达式写法
{
if(a[0] == b[0])
return a[1] - b[1];
return b[0] - a[0];
});
LinkedList que = new LinkedList<>();
for(int[] p:people)
{
que.add(p[1],p);//这里其实就是找k值作为下标尾插的过程
}
return que.toArray(new int[people.length][]);
}
}
题目链接:452. 用最少数量的箭引爆气球 - 力扣(LeetCode)
这题我们可以先在数轴上把这个区间画出来,模拟一下,我们可以按照左区间排序,也可以按照右区间排序,这里我们按照升序排列,如图所示
这里我们发现只要当前区间的左区间大于上一个气球的右区间,就没有重叠,我们就需要多增加一支弓箭,否则就更新右区间,这样是考虑三个气球重叠的情况或者更多气球重叠的情况,将右区间更新为两个右区间中较小的一个即可.
class Solution {
public int findMinArrowShots(int[][] points) {
if(points.length == 0)
{
return 0;
}
int result = 1;
Arrays.sort(points,(a,b)->Integer.compare(a[0],b[0]));
for(int i = 1;ipoints[i-1][1])
{
result++;
}
else
{
points[i][1] = Math.min(points[i][1],points[i-1][1]);
}
}
return result;
}
}
这道题目贪心的思路很简单也很直接,就是重复的一起射了,但本题我认为是有难度的。
就算思路都想好了,模拟射气球的过程,很多同学真的要去模拟了,实时把气球从数组中移走,这么写的话就复杂了。
而且寻找重复的气球,寻找重叠气球最小右边界,其实都有代码技巧。
贪心题目有时候就是这样,看起来很简单,思路很直接,但是一写代码就感觉贼复杂无从下手。