代码随想录算法训练营 Day 35 | 860.柠檬水找零,406.根据身高重建队列,452.用最少数量的箭引爆气球

860.柠檬水找零

讲解链接:代码随想录-860.柠檬水找零

public boolean lemonadeChange(int[] bills) {
    // 手里的零钱数量
    int[] balance = new int[4];
    for (int i = 0; i < bills.length; i++) {
        // 需要给客户的钱
        int giveChange = bills[i] - 5;
        int start = 1;
        // 循环手里的余额,从大的开始给,因为题目里能给客户的钱最大的为10,所以直接从下标1开始
        while (giveChange > 0 && start >= 0) {
            // 当前纸币下标对应的金额
            int amount = (start + 1) * 5;
            // 如果找的零小于纸币、纸币数量小于等于0,就递减,用更小的纸币。
            if (giveChange < amount || balance[start] <= 0) {
                start--;
                continue;
            }
            giveChange -= amount;
            balance[start]--;
        }
        // 如果手里的钱用完了,还是没找开,就返回false
        if (giveChange > 0) {
            return false;
        }
        balance[bills[i] / 5 - 1]++;
    }
    return true;
}

406.根据身高重建队列

讲解链接:代码随想录-406.根据身高重建队列

贪心

public int[][] reconstructQueue(int[][] people) {
    // 根据身高降序;如果身高相同,根据序号升序。
    Arrays.sort(people, (a, b) -> {
        if (a[0] == b[0]) return a[1] - b[1];
        else return b[0] - a[0];
    });
    // 按照顺序遍历,身高高的人会被先插入指定下标,矮的后插入指定下标,
    // 这样就会排在身高高的前面,保证序号正确。
    LinkedList<int[]> list = new LinkedList<>();
    for (int i = 0; i < people.length; i++) {
        list.add(people[i][1], people[i]);
    }
    // 注意转换为数组的流操作,不记得就循环吧。
    return list.toArray(new int[list.size()][]);
}

暴力破解

public int[][] reconstructQueue(int[][] people) {
    int[][] result = new int[people.length][];
    // 身高从低到高排序
    Arrays.sort(people, (a, b) -> a[0] - b[0]);
    for (int i = 0; i < result.length; i++) {
        for (int j = 0; j < people.length; j++) {
            if (people[j] == null) continue;
            int[] p = people[j];
            int count = 0;
            for (int k = 0; k < i; k++) {
                int[] r = result[k];
                if (r[0] >= p[0]) {
                    count++;
                }
            }
            if (count == p[1]) {
                result[i] = people[j];
                people[j] = null;
                break;
            }
        }
    }
    return result;
}

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

讲解链接:代码随想录-452.用最少数量的箭引爆气球

public int findMinArrowShots(int[][] points) {
    // 根据气球直径的开始坐标从小到大排序,这里有边界值,直接用-法会溢出
    Arrays.sort(points, (a, b) -> {
        if (a[0] < b[0]) {
            return -1;
        } else {
            return 1;
        }
    });

    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;
}

总结

好难

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值