算法练习day30

66 阅读1分钟

一、柠檬水找零

只有5和10可以找零,5可以对10,20找零,10可以对20找零,分别记录5和10的总数,优先用10找零,否则用5

/**
 * @param {number[]} bills
 * @return {boolean}
 */
var lemonadeChange = function(bills) {
    let fiveCount = 0
    let tenCount = 0
    for(let i = 0; i < bills.length; i++) {
        if(bills[i] === 5) {
            fiveCount++
        } else if(bills[i] === 10) {
            if(fiveCount > 0) {
                fiveCount--
                tenCount++
            } else {
                return false
            }
        } else {
            if(fiveCount > 0 && tenCount >0) {
                fiveCount--
                tenCount--
            } else if(fiveCount>=3) {
                fiveCount-=3
            } else {
                return false
            }
        }
    }
    return true
};

二、根据身高重建队列

局部最优:优先按身高高的人的k来插入

/**
 * @param {number[][]} people
 * @return {number[][]}
 */
var reconstructQueue = function(people) {
    let res = []
    people.sort((a, b) => {
        if(a[0] !== b[0]) {
            return b[0] - a[0]
        } else {
            return a[1] - b[1]
        }
    })
    for(let i = 0; i < people.length; i++) {
        res.splice(people[i][1], 0, people[i])
    }
    return res
};

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

关键在于通过排序,尽量重叠,及时更新右侧最小位置,找到重叠气球,如果不满足重叠,则箭的数量增加

/**
 * @param {number[][]} points
 * @return {number}
 */
var findMinArrowShots = function(points) {
    let count = 1
    points.sort((a, b) => a[0] - b[0])
    for(let i = 1; i < points.length;i++) {
        // 如果当前气球的左位置大于上个气球的最小右位置,说明需要一个新的箭
        if(points[i][0] > points[i-1][1]){
            count++
        } else {
            // 否则当前气球和上个气球发生重叠,更新最小右位置,进行一个气球的比较
            points[i][1] = Math.min(points[i-1][1], points[i][1])
        }
    }
    return count
};