LeetCode check-in day35--Lemonade change, use the least number of arrows to detonate the balloon, rebuild the queue according to the height


knowledge summary

Greedy algorithm, use local optimum to derive global optimum


Leetcode 860. Lemonade Change

topic link

topic description

At the lemonade stand, a glass of lemonade sells for $5. Customers line up to buy your products, one cup at a time (in the order bills are paid).

Each customer buys just one glass of lemonade and pays you $5, $10, or $20. You have to give each customer the correct change, which means the net transaction is that each customer pays you $5.

Note that you don't have any change on hand at first.

You are given an integer array bills, where bills[i] is the bill paid by the i-th customer. Return true if you were able to give each customer correct change, otherwise return false.

insert image description here

code description

Just record the number of sheets of five yuan and ten yuan.

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

Leetcode 452. Detonate a Balloon with the Minimum Number of Arrows

topic link

topic description

There are spherical balloons attached to a wall represented by an XY plane. The balloons on the wall are recorded in the integer array points, where points[i] = [xstart, xend] means the balloons whose horizontal diameter is between xstart and xend. You don't know the exact y coordinate of the balloon.

A bow and arrow can be shot perfectly vertically from different points along the x-axis. Shoot an arrow at coordinate x, if there is a balloon whose diameter starts and ends at coordinates xstart, xend and satisfies xstart ≤ x ≤ xend, the balloon will be detonated. There is no limit to the number of bows that can be shot. Once the bow and arrow is shot, it can move forward indefinitely.

Given an array points, return the minimum number of arrows that must be shot to explode all balloons.
insert image description here

code description

Method 1:
This question is a bit similar to the previous merging intervals. You can use a similar method, but this time the newly added intervals are not unions, but intersections. If there are no intersecting parts, then add a new interval to the list. Learning In the way of sorting, if you write subtraction directly, there will be an out-of-bounds problem with the maximum value of Integer, so you must override the compare method.

class Solution {
    
    
    public int findMinArrowShots(int[][] points) {
    
    
        if(points.length == 1){
    
    
            return 1;
        }

        // Arrays.sort(points, 
        //     (a1, a2) -> a1[0] - a2[0]
        // );

		// 按照左边界的大小排序
        Arrays.sort(points, new Comparator<int[]>(){
    
    
            public int compare(int[] point1, int[] point2){
    
    
                if(point1[0]> point2[0]){
    
    
                    return 1;
                }else if (point1[0] < point2[0]){
    
    
                    return -1;
                }else{
    
    
                    return 0;
                }
            }
        });

        LinkedList<int[]> list = new LinkedList<>();
        int left =0, right = 0;
        list.add(points[0]);
        for(int i = 1; i < points.length; i++){
    
    
            left = points[i][0]; 
            right = points[i][1];
            if(left<= list.getLast()[1]){
    
    
                list.getLast()[0] = Math.max(list.getLast()[0], left);
                list.getLast()[1] = Math.min(list.getLast()[1], right);

            }else{
    
    
                list.add(points[i]);
            }
        }
        return list.size();
    }
}

Method 2;
different from the above, we sort in ascending order according to the size of the boundary. Then in order to shoot as many balloons as possible, we will shoot the rightmost position of the first one, and then if the left boundary of a new interval If it is greater than this pos, it means that the original arrow failed to hit this range, and a new arrow needs to be shot again.
insert image description here

class Solution {
    
    
    public int findMinArrowShots(int[][] points) {
    
    
        if(points.length == 1){
    
    
            return 1;
        }

        // Arrays.sort(points, 
        //     (a1, a2) -> a1[1] - a2[1]
        // );
			
        Arrays.sort(points, new Comparator<int[]>(){
    
    
            public int compare(int[] point1, int[] point2){
    
    
                if(point1[1]> point2[1]){
    
    
                    return 1;
                }else if (point1[1] < point2[1]){
    
    
                    return -1;
                }else{
    
    
                    return 0;
                }
            }
        });

        int pos = points[0][1];
        int ans = 1;
        for(int[] bollon : points){
    
    
            if(bollon[0] > pos){
    
    
                pos = bollon[1];
                ans++;
            }
        }
        return ans;
    }
}


Leetcode 406. Rebuild Queue Based on Height

topic link

topic description

Suppose a group of people in random order stand in a queue, and the array people represents the attributes of some people in the queue (not necessarily in order). Each people[i] = [hi, ki] means that the height of the i-th person is hi, and there are exactly ki people whose height is greater than or equal to hi in front.

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

insert image description here

code description

Take the time to read the title first, and after sorting, it should be [5, 0], which means that the height of this person is 5, and there are 0 people with a height >= 5

Solving the problem is still quite difficult, and then many Java code skills and syntactic sugar.

  1. Sort by height first and then by k value
        Arrays.sort(people,
            (a, b) -> {
                if(a[0] == b[0]) return a[1] - b[1]; // 身高相同, k值升序排列
                return b[0] - a[0]; // 否则优先按身高降序排列
            }
        );
  1. Inserts an element at the specified position.

LinkedList.add(index, value)

  1. Convert the list to an array, remember to write the size of the array

queue.toArray(new int[people.length][]

class Solution {
    
    
    public int[][] reconstructQueue(int[][] people) {
    
    
        Arrays.sort(people,
            (a, b) -> {
    
    
                if(a[0] == b[0]) return a[1] - b[1]; // 身高相同, k值升序排列
                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][]);
    }
}

Guess you like

Origin blog.csdn.net/weixin_45872648/article/details/131194668