思路
只需要维护3种金额的数量
三种情况 :
1: 5 直接收下
2: 10 消耗5 增加10
3:20 优先消耗1个10 1个5 或者 3个5
贪心:10只能给20美元找0 5美元更万能
局部最优:遇到20 优先消耗10 完成本次找0
全局最优:完成全部账单的找0
思路
/**
* @param {number[][]} people
* @return {number[][]}
*/
var reconstructQueue = function(people) {
let queue = []
// 身高从大到小排(身高相同k小的站前面)
// people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
people.sort((a,b)=>{
if(b[0]!==a[0]){
return b[0]-a[0]//从大到小排 a b 是数组 [0] 是身高 [1]是 前面有多少人比他高
}else {
return a[1]-b[1]//身高相同 k小的站前面
}
})
// splice 方法 在数组中删除指定元素 或者插入元素
// 参数为3个 (i,j,e) i表示索引起始位置 j 表示删除个数 e 要添加的元素
// 从索引为i位置开始删除j个元素 然后从i位置添加e
// j=0 表示一个元素也不删除 从i前一个位置开始插入
// 再按照k进行插入 优先插入k小的
for(let i=0;i<people.length;i++){
queue.splice(people[i][1],0,people[i])
}
return queue
};
本题有两个维度 h k
看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。
那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。
此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!
所以在按照身高从大到小排序后:
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
局部最优可推出全局最优,找不出反例,那就试试贪心。
思路
局部最优:当气球出现重叠,一起射,所用弓箭最少。
全局最优:把所有气球射爆所用弓箭最少
算法确定下来了,那么如何模拟气球射爆的过程呢?是在数组中移除元素还是做标记呢?
但仔细思考一下就发现:如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。