代码随想录算法训练营第三十五天 _ 贪心_860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球

学习目标:

60天训练营打卡计划!

学习内容:

860.柠檬水找零

  • 本题看起来情况很多,其实只有3种,所以可以用贪心算法。
  • 但确实还是不清楚贪心体现在哪里。
class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;
        int twelve = 0;
        for(int bill : bills){
            if(bill == 5) five++;
            if(bill == 10){
                if(five > 0){
                    five--;
                    ten++;
                }
                else 
                    return false;
            }
            if(bill == 20){
                if(ten > 0 && five > 0){
                    ten--;
                    five--;
                    twelve++;
                }
                else if(five >= 3){
                    five -= 3;
                    twelve++;
                }
                else 
                    return false;
            }
        }
        return true;
    }
}

406.根据身高重建队列

  • 本题看起来情况很多,确实很难。
  • 优先掌握Arrays.sort()这种排列方法,其次一定要会一种手动排序的方法(插入就很不错!)
  • 一定要学会这种思路,很有参考的价值。就是使用两种策略分别处理一个数组,可以减少同时操作时带来的误判。
class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 使用插入排序,实现自定义的排序
        // 即:根据身高排序,身高相同时,k越大越靠后。
        // for(int i = 1; i < people.length; i++){
        //     int[] key = people[i];
        //     int j = i - 1;
        //     while((j >= 0 && people[j][0] < key[0] )
        //     || (j >= 0 && people[j][0] == key[0] && people[j][1] > key[1])){
        //         people[j+1] = people[j];
        //         j--;
        //     }
        //     people[j+1] = key;
        // }
        // 前大后小
        Arrays.sort(people, (a, b) -> {
            if(a[0] == b[0])  return a[1] - b[1];   // a - b 是升序排列 ,根据k升序排列
            return b[0] - a[0];   //b - a 是降序排列, 根据h降序排列
        });
        // LinkedList类,有 add(int index, E element) 方法
        // 允许你在指定位置插入元素。
        LinkedList<int[]> que = new LinkedList<>();

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

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

  • 引爆气球的时候,不需要真的对数组做什么操作,只要从这行数组遍历完就可以算是引爆了当前行的气球;
  • 通过for循环逐行检查是否和上一行可以被同时引爆;
    还没学会如何孤立变量更好的实现题目的要求。 一定要学会这个思路,脑袋里全是回溯,希望可以同时比较两边,殊不知一边一边的比较会更清晰也更好实现。
  • 如果两行气球可以被一起引爆,则将两者的右边界同时调整为较小的那个值。
class Solution {
    public int findMinArrowShots(int[][] points) {
        // 使用Integer内置比较方法,不会溢出
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
        
        // 至少用一个箭头 i = 0
        int res = 1;
        for(int i = 1; i < points.length; i++){
            // 第i-1行和第i行没有重叠
            if(points[i][0] > points[i-1][1])
                res++;
            // 有重叠则设置该行的长度为两行中右侧最小的值,
            else{
                points[i][1] = Math.min(points[i][1], points[i-1][1]);
            }
        }
        return res;
    }
}

学习时间:

  • 上午两小时,下午一个半小时,整理文档半小时。
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值