随想录训练营Day35 | 贪心 - - 860.柠檬水找零, 406.根据身高重建队列

53 阅读1分钟

随想录训练营Day35 | 贪心 - - 860.柠檬水找零, 406.根据身高重建队列

标签: LeetCode闯关记


860.柠檬水找零

思路: 有且仅有三种情况,针对bills[i] == 20,因为5元相比10元的找零更灵活,所以优先用10元,囤5元;

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++;
            }
            if(bills[i] == 10){
                if (five > 0){
                    ten++;
                    five--;
                }else{
                    return false;
                }
            }
            if(bills[i] == 20){
                if(ten > 0 && five > 0){
                    ten--;
                    five--;
                }else if (five >= 3){
                    five -= 3;
                }else{
                    return false;
                }
            }
        }
        return true;
    }
}

406.根据身高重建队列

毁灭吧

//彻底不太看得懂语法了
class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people,(a,b) ->{
            if(a[0] == b[0]){
                return a[1] - b[1];
            }
            return b[0] - a[0];
        });
        LinkedList<int[]> queue = new LinkedList<>();
        //段代码是将元素 p 插入到 LinkedList 的 p[1] 位置上,也就是说,如果 LinkedList 中已经有了 p[1] 个元素,则新加入的元素会放在这些元素之后。如果 p[1] 为 0,则表示这个人应该插入到队列的最前面。
        //因为在排序后遍历 people 数组时,我们是按照身高从大到小的顺序遍历的,所以对于每个人,前面所有身高比它高(或相同)的人都已经被插入到了 LinkedList 中,而它们的 k 值肯定小于等于当前这个人的 k 值。因此,当前这个人插入时使用的索引应该是其 k 值,这样才能保证所有在它前面的人都已经被插入过了,而它自己插入时,只要考虑自己的 k 值即可。

        for (int[] p : people) {
            queue.add(p[1], p);
        }
        return queue.toArray(new int[people.length][]);


    }
}
/*
1) 根据代码 que.add(p[1],p) 推测,这是一个将一个二元组(p)插入优先队列(que)中的操作。一般来说,优先队列需要支持以下两个操作:

add(priority, item):将一个元素 item 按照给定的优先级 priority 插入队列中;
pop():弹出队列中优先级最高的元素。
通常我们使用堆这种数据结构实现优先队列,其中 add(priority, item) 操作对应将元素插入堆中,pop() 操作则将堆顶元素取出,这样就保证了每次取出的元素都是当前堆中优先级最高的。具体来说,当我们调用 add(priority, item) 时,可以先将 item 和 priority 封装成一个节点,然后将该节点插入堆中即可。此时堆会根据节点中的优先级自动维护元素的位置。因此,我猜测在 que.add(p[1],p) 中,que 可能是一个堆,调用 add(p[1],p) 方法即向堆中插入一个元素 p,p[1] 则是 p 的优先级。
2) new int[people.length][] :
这是一个Java中创建二维数组的语法。其中people.length表示一维数组的长度,也即第一维的大小;而后面的方括号[]则表示第二维的大小不确定,需要在之后给定。
换句话说,这行代码创建了一个二维整型数组,其中第一维的大小为people数组的长度,第二维的大小暂时未确定,需要在之后动态地进行初始化。
 */

time:1h10min

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

key:

  • 思路很简单,即找到重叠气球则不射箭,不是重叠气球则射箭
  • 模拟射箭的过程,不需要remove数组中的元素,只需要统计箭的个数
  • 初始话箭的count为1,因为points.length >=1,之后的for循环中,从第二个气球(下标为1)开始遍历,找到了重叠气球不用count++,但是需要更新最小右边界,为后续的比较更新points[i-1][1];
class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points,(a,b) -> Integer.compare(a[0],b[0]));
        int count = 1;
        for (int i = 1; i < points.length; i++) {
            if(points[i][0] <= points[i-1][1]){//要是气球i和气球i-1挨着,更新重叠气球最小右边界
                points[i][1] = Math.min(points[i-1][1], points[i][1]);
            }else{//气球i和气球i-1不挨着
                count++;// 需要一支箭
            }
        }
        return count;

    }
}