代码随想录Day37

860.柠檬水找零

题目:860. 柠檬水找零 - 力扣(LeetCode)

思路:先用元素全为5的数组去减bills数组,得到找零数组,之后遍历bills数组,去把找零数组元素全部变为零,怎么填补我想不出来

尝试(部分AC)
class Solution {
    public boolean lemonadeChange(int[] bills) {
        Arrays.sort(bills);
        int[] gap = new int[bills.length]; 
        for(int i =0; i<bills.length; i++){
            gap[i] = 5 - bills[i];
        }
        int result = 0;
        int index = 0;
        for(int i : gap){
            if(i<0){
                while(result + i < 0 && index < bills.length){
                    result += bills[index];
                    index++;
                }
                if(result + i > 0){
                    return false;
                }
            }
        }
        return true;
    }
}
答案
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;
    }
}
小结
  • 简单粗暴的处理逻辑,直接把所有情况都列出来
  • 这是单步操作,遍历bills数组,挨个判断处理

406.根据身高重建队列

题目:406. 根据身高重建队列 - 力扣(LeetCode)

思路:我想不到遍历要怎么处理

答案
class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 身高从大到小排(身高相同k小的站前面)
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
            return b[0] - a[0];   //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
        });

        LinkedList<int[]> que = new LinkedList<>();

        for (int[] p : people) {
            que.add(p[1],p);   //Linkedlist.add(index, value),會將value插入到指定index裡。
        }

        return que.toArray(new int[people.length][]);
    }
}

小结
  • 需要考虑两个维度的问题,要先确定一个,不要身高和个数同时考虑
  • que.add(p[1],p);】这个队列函数很关键!可以插入到指定的【p[1]】下标处
  • 身高从大到小排,同身高的k小的排前面,之后用队列的插入函数
  • people[i] = [hi, ki] ,【ki】表示了有几个元素比当前元素大,所以先身高从大到小排,后面插入的时候,直接根据【ki】的信息,就能找到插入的位置,因为前面的元素都是比自己要大的,遍历的时候就是从大到小遍历,而且插入小身高的元素,并不会影响大身高的元素,秒!
  • Comparator是一个用于比较大小的函数式接口,简单来说【只要记住,返回a - b,就是升序排序,返回b - a就是降序排列】
Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列
            return b[0] - a[0];   //b - a 是降序排列
        });

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

题目:452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

思路:找重叠区间,逐个扫描区间,把区间范围内的元素加1,全部元素扫描完成之后,就知道了重叠区间,把带有重叠区间信息的数组排序一遍,取出最大的几个元素,直到加起来数字超过气球个数,每加一个数就相当于射出一箭,最后返回这个数

尝试(部分AC)
class Solution {
    public int findMinArrowShots(int[][] points) {
        // 升序排列,根据区间的结束时间进行排序
        Arrays.sort(points, (a, b) -> a[1] - b[1]);

        // 初始化record数组,长度为最后一个区间的结束时间
        int maxLength = points[points.length - 1][1];
        int[] record = new int[maxLength + 1]; // 需要+1因为数组索引从0开始

        // 遍历points数组的元素,将每个元素当作区间
        for (int[] p : points) {
            // 遍历区间的开始时间和结束时间
            for (int i = p[0]; i <= p[1]; i++) {
                // 给record数组对应的区间数字加上1
                record[i]++;
            }
        }
        Arrays.sort(record);
        int result = 0;
        int count = 0;
        int index = record.length -1;
        while(result < points.length){
            result += record[index];
            index--;
            count++;
        }
        return count;
    }
}
答案
class Solution {
    public int findMinArrowShots(int[][] points) {
        // 根据气球直径的开始坐标从小到大排序
        // 使用Integer内置比较方法,不会溢出
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));

        int count = 1;  // points 不为空至少需要一支箭
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > points[i - 1][1]) {  // 气球i和气球i-1不挨着,注意这里不是>=
                count++; // 需要一支箭
            } else {  // 气球i和气球i-1挨着,区间有重叠,那就合并区间
                points[i][1] = Math.min(points[i][1], points[i - 1][1]); // 更新重叠气球最小右边界
            }
        }
        return count;
    }
}
小结
  • 我的方法不行,因为数字范围很大的时候,就要建立一个很大的数组,会超出内存
  • 卡尔的思路就是,先把元素从小到大排序,然后相邻的区间逐个合并,不能合并时,就射出一支箭
  • 要用【Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));】才不会溢出
  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值