代码随想录算法训练营第三十四天| LeetCode860.柠檬水找零、LeetCode406.根据身高重建队列、LeetCode452. 用最少数量的箭引爆气球

#LeetCode 860. Lemonade Change

#LeetCode 860. 视频讲解:贪心算法,看上去复杂,其实逻辑都是固定的!LeetCode:860.柠檬水找零_哔哩哔哩_bilibili

如果收到的是5 或者10 的纸币,那么找零的选择是固定的,并不需要考虑贪心策略。所以贪心策略应用于收到20 的纸币时,这个时候的局部最优是先用10 和5 的纸币找零,因为5 可以用于给10 找零,所以全剧最优是可以对所有的柠檬水找零。

贪心算法代码:

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;
        int twenty = 0;
        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five ++;
            }
            else if (bills[i] == 10) {
                if (five == 0) {
                    return false;
                } else {
                    ten ++;
                    five --;
                }
                if (five < 0) {
                    return false;
                }
            }
            else {
                twenty++;
                if (ten > 0 && five > 0) {
                    ten --;
                    five --;
                }
                else if (five >= 3) {
                    five -= 3;
                }
                else {
                    return false;
                }
            }
        }
        return true;
    }
}

#LeetCode 406. Queue Reconstruction by Height

#LeetCode 406. 视频讲解:贪心算法,不要两边一起贪,会顾此失彼 | LeetCode:406.根据身高重建队列_哔哩哔哩_bilibili

第一个难点是理解题目... 理解题目后,需要考虑是先按照h 排序还是k 排序。观察正确排序的数组,k 是按照从小到大的顺序来排序的,代表的是前面有k 个大于等于当前h 的数字。再考虑按照h 排序,正确的方法是h 按照从大到小的顺序排序,这样再次按照k 进行插值,可以保证前面的数字是大于当前的h 的,也不会影响后面的数字的顺序,因为h 已经从大到小排序,放入前面的数字都比当前数字小。

Java 的算法中,用的是Arrays.sort 实现的,Lambda 表达式中,a - b 表达的是降序,b - a 表达的是升序。如果height 相同,那么就按照k 值升序排序,如果height 不同,那么直接按照降序排序。

使用队列来排序,可以根据index 和value 直接进行插值排序。在最后返回时需要将队列转换回数组返回。

贪心算法代码:

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<>();

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

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

#LeetCode 452. Minimum Number of Arrows to Burst Balloons

#LeetCode 452. 视频讲解:贪心算法,判断重叠区间问题 | LeetCode:452.用最少数量的箭引爆气球_哔哩哔哩_bilibili

题目中的局部最优是当气球出现重叠,只用一支弓箭。全局最优是用最少的弓箭引爆所有气球。

本题的难点是如何记录重叠气球,思路是先将无序的气球按照左边节点值排序,将气球尽可能的相邻。判断两个相邻气球是否有重叠难度不大,如何判断三个气球是否相邻,这是本题中需要考虑的要点。解题方法是用point[i - 1][0] 变量来记录右边界,每次都会更新右边界,用最小的值来代替右边边界的值。

贪心算法代码:

class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points.length == 0) {
            return 0;
        }
        Arrays.sort(points, (a,b) -> Integer.compare(a[0], b[0]));
        int result = 1;
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > points[i-1][1]) {
                result ++;
            } else{
                points[i][1] = Math.min(points[i][1], points[i-1][1]);
            }
        }
        return result;
    }
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值