第八章 贪心算法 part04

72 阅读1分钟

860. Lemonade Change

At a lemonade stand, each lemonade costs $5. Customers are standing in a queue to buy from you and order one at a time (in the order specified by bills). Each customer will only buy one lemonade and pay with either a $5$10, or $20 bill. You must provide the correct change to each customer so that the net transaction is that the customer pays $5.

Note that you do not have any change in hand at first.

Given an integer array bills where bills[i] is the bill the ith customer pays, return true if you can provide every customer with the correct change, or false otherwise.

题目解析

  • 先找10块的再找5块的

代码:

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int[] changes = new int[2]; // 5, 10
        for (int bill: bills) {
            if (bill == 5) {
                changes[0]++;
            } else if (bill == 10) {
                changes[1]++;
                changes[0]--;
                if (changes[0] < 0) return false;
            } else {
                if (changes[1] > 0) {
                    changes[1]--;
                    changes[0]--;
                } else {
                    changes[0] -= 3;
                }
                if (changes[0] < 0) return false;
            }
        }
        return true;
    }
}

406. Queue Reconstruction by Height

You are given an array of people, people, which are the attributes of some people in a queue (not necessarily in order). Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki other people in front who have a height greater than or equal to hi.

Reconstruct and return the queue that is represented by the input array people. The returned queue should be formatted as an array queue, where queue[j] = [hj, kj] is the attributes of the jth person in the queue (queue[0] is the person at the front of the queue).

题目解析:

  • 如果需要考虑两个维度,可以确定一边然后贪心另一边,两边一起考虑,就会顾此失彼。
  • 如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!

代码:

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[]> result = new LinkedList<>();
        for (int[] person: people) {
            result.add(person[1], person);
        }
        return result.toArray(new int[0][]);
    }
}

452. Minimum Number of Arrows to Burst Balloons

There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array points where points[i] = [xstart, xend] denotes a balloon whose horizontal diameter stretches between xstart and xend. You do not know the exact y-coordinates of the balloons.

Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with xstart and xend is burst by an arrow shot at x if xstart <= x <= xend. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.

Given the array points, return the minimum number of arrows that must be shot to burst all balloons.

代码:

class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points, (a, b) -> {
            if (a[0] == b[0]) {
                return Integer.compare(a[1], b[1]);
            }
            return Integer.compare(a[0], b[0]);
        });
        int count = 1;
        int[] curInterval = new int[2];
        curInterval[0] = points[0][0];
        curInterval[1] = points[0][1];
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > curInterval[1]) {
                count++;
                curInterval[0] = points[i][0];
                curInterval[1] = points[i][1];
            } else {
                if (points[i][1] < curInterval[1]) {
                    curInterval[1] = points[i][1];
                } 
                curInterval[0] = points[i][0];
            }
        }
        return count;
    }
}