LeetCode刷题day35|860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球

文章目录

  • 一、860.柠檬水找零
  • 二、406.根据身高重建队列
  • 三、452. 用最少数量的箭引爆气球

一、860.柠檬水找零

这道题刚开始做会踩坑,想着只要手中的钱够找零就行了,结果报错——因为面值为20元需要一张5元面值和一张10元面值来找零,如果手中没有了5元面值,也是行不通的。
因此,可以换一种思路:看手中的5元和10元面值数量够不够(20元不用统计,因为不会用于找零)。

以下是代码部分:

	//记录5元、10元 的数量
    public boolean lemonadeChange2(int[] bills) {

        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {

            if(bills[i] == 5)
                five++;
            else if(bills[i] == 10){
                ten++;
                five--;
            }else{
                if(ten!=0){
                    ten--;
                    five--;
                }else {
                    five -= 3;
                }
            }

            //如果5元币的数量减到负数
            if(five <0 )
                return false;
        }
        return true;
    }

二、406.根据身高重建队列

这道题是比较有难度的。
主要思路:数组有两个维度,所以从两个维度来进行排序。首先是身高,从大到小排——这是因为高身高是最容易决定相对位置的。
低身高依赖于高身高而存在,当高身高定好位置,低身高就依据k值来定他前边应该有几个比他高的(比他高的都排好相对位置了,他只需要插入位置即可)
当然,这道题还有两点注意:

  1. lambda表达式 Arrays.sort( nums, (a,b) -> a-b ),这是升序排列。(lambda表达式其实就是把方法当作参数。)
  2. LinkList.add( index, object)

以下是代码部分:

public class 根据身高重建队列406 {

    //从大到小排的原因:在插入的时候,先插入高的,肯定会定到最终的相对位置。在插入时,依据k的值进行插入,
    public int[][] reconstructQueue(int[][] people) {

        //lambda表达式
        Arrays.sort(people, (a,b) -> {
            //如果身高相等,则按k从小到大输出
            if( a[0] == b[0])
                return a[1] - b[1];
            //按身高从大到小输出
            return b[0] - a[0];
        });

        LinkedList<int[]> res = new LinkedList<>();

        for (int[] person : people) {

            //依据people[1]的值依次插入到链表res
            res.add(person[1], person);
        }

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

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

主要思路:依据左点排序,并收集最小的右点,当最小右点小于新的左点时,就不能再继续放一块了。
需要注意的点:排序的时候需要使用Integer内置比较方法,否则会溢出。

		// 使用Integer内置比较方法,不会溢出
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));

以下是代码部分:

public class 用最少数量的箭引爆气球452 {

    //思路:依据左点排序,并收集最小的右点,当右点小于新的左点时,就不能再继续放一块了
    public int findMinArrowShots(int[][] points) {

        int res = 1;

        /**
         *
        //依据左点进行排序 lambda表达式
        //用这个比较方法溢出了!!!
        Arrays.sort(points, (a, b) -> {
            if(a[0] == b[0])
                return a[1] - b[1];
            return a[0] - b[0];
        });
         */

        // 使用Integer内置比较方法,不会溢出
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));

        //记录当前集合中最小的右点
        int minRight = points[0][1];

        for (int i = 1; i < points.length; i++) {

            //当最小右点大于新的左点
            while ( i < points.length && minRight >= points[i][0] ){
                //更新最小右点
                minRight = Math.min( minRight, points[i][1]);
                //i++
                i++;
            }

            //如果i遍历到最后
            if( i == points.length )
                return res;

            res++;
            //更新新的一组中的最小右点
            minRight = points[i][1];
        }
        return res;
    }
}

你可能感兴趣的:(leetcode,java,算法)