【刷题day35】贪心算法 | 860.柠檬水找零、406.根据身高重建队列、 452. 用最少数量的箭引爆气球

860.柠檬水找零

题目讲解

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five++;
            } else if (bills[i] == 10) {
                five--;
                ten++;
            } else if (bills[i] == 20) {
                if (ten > 0) {
                    ten--;
                    five--;
                } else {
                    five -= 3;
                }
            }
            if (five < 0 || ten < 0) return false;
        }
        
        return true;
    }
}

406.根据身高重建队列

题目讲解

思路:对于本题困惑的点是先确定k还是先确定h呢,也就是究竟先按h排序呢,还是先按照k排序呢?

如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。

那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。

此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!

那么只需要按照k为下标重新插入队列就可以了

class Solution {
    public int[][] reconstructQueue(int[][] people) {
    	// 身高从大到小排(身高相同k小的站前面)
    	Comparator<int[]> cmp = new Comparator<int[]>() {
			@Override
			//compare方法,当方法的返回值大于0的时候就将列表的前一个数o1和后一个数o2做交换
			public int compare(int[] o1, int[] o2) {
				//注意此处o1与o2位置
				if (o1[0] == o2[0]) return o1[1] - o2[1];
				//注意若要调用compareTo,必须是包装类型
				//return Integer.valueOf(o2[0]).compareTo(Integer.valueOf(o1[0])); // 等价于o2-o1
	            return o2[0] - o1[0];
			}
		};
    	Arrays.sort(people, cmp);
    	
        LinkedList<int[]> que = new LinkedList<>();//底层列表,插入比arraylist更快
        for (int[] p : people) {
            que.add(p[1],p);
        }
        return que.toArray(new int[people.length][]);
    }
}

452. 用最少数量的箭引爆气球

题目讲解

自定义排序的注意事项:
○ 注意:若要调用compareTo,必须是包装类型,若为int则需要Integer.valueOf()转为Integer
○ 注意:建议使用compareTo而不是直接减。eg.若被减数为int最小值-2147483648,减去1则会变成int的最大值2147483647,会出错的!!!

class Solution {
    public int findMinArrowShots(int[][] points) {
        //按照左边界排序
        
         Arrays.sort(points, new Comparator<int[]>() {
             @Override
             public int compare(int[] o1, int[] o2) {
             //注意:若按照以下方法会出错
             //return o1[0]-o2[0];
             //当o1[0]为int最小值时,会返回出错
                 return Integer.valueOf(o1[0]).compareTo(Integer.valueOf(o2[0]));
             }
         });
        // Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
        int ans = 1;//题中points长度大于等于1,第一个重叠区间默认需要一根
        int minR = points[0][1]; //记录最小右边界
        //从第二个气球开始遍历寻找下一个重叠区间(需要增加的箭数)
        for (int i = 1; i < points.length; i++) {
            //左边界在本重叠区间的最小右边界内,说明仍在本区间,依旧可以射到
            if (points[i][0] <= minR) {
                minR = Math.min(minR, points[i][1]);//更新最小右边界
            }else{//左边界大于本重叠区间的最小右边界,新的重叠区间开始,需要增加箭数并重置最小右边界
                ans++;
                minR = points[i][1];//注意:更新!!否则一直用的是第一个气球的右边界
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值