860.柠檬水找零
- 406.根据身高重建队列
- 452. 用最少数量的箭引爆气球
第一题:柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5
美元。顾客排队购买你的产品,(按账单 bills
支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5
美元、10
美元或 20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5
美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills
,其中 bills[i]
是第 i
位顾客付的账。如果你能给每位顾客正确找零,返回 true
,否则返回 false
。
- 输入:[5,5,10,10,20]
- 输出:false
- 解释:
- 前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
- 对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
- 对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
- 由于不是每位顾客都得到了正确的找零,所以答案是 false。
其实一共三种情况:
(1)账单是5,直接收下;
(2)账单是10,消耗一个5,增加一个10
(3)账单是20,优先消耗一个10和5,如果不够消耗3个5
情况1,2都是固定情况,对于情况可以进行判断,因为5更全能,尽可能的保留5,先用10
局部最优:遇到账单20,优先消耗10,完成本次找零
全局最优:完成全部账单的找零
第二题:按照身高重建队列
假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。
本题和分发糖果类似,排序需要考虑两个维度,“遇到两个维度权衡的时候,一定要先确定一个维度,在确定另一个维度”
1、先考虑身高h维度,从大到小排列,(身高相同的,k小的在前面),让高个子在前面
2、然后直接根据k的值插入就行,因为比如(5,2)它前面的数值肯定大于等于它,而它前面只能有2个大于等于它的数据,所以插入下标为2的位置
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
别的都可以理解,这一段关于排序的:
static bool cmp(const vector<int> &a,const vector<int> &b){
if(a[0]==b[0]) return a[1]<b[1];
return a[0]>b[0];
}
sort(people.begin(),people.end(),cmp);
关于sort函数:
void sort (RandomAccessIterator first, RandomAccessIterator last);
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
第一种:默认排序,两个参数first
,last
,将[first, last)
区间内元素升序排列。【注意区间为左闭右开】
第二种:自定义排序,需用户指定排序规则Compare comp
,将 [first, last)
区间内的元素按照用户指定的顺序排列。
也就是说,该段代码根据cmp指定的规则排序,这里的规则直接将身高的前面的人数都放进去了,不是简单的按照身高降序排列,而是如果两人身高相等,就将前面人数小的放前面;如果身高不相等,将身高高的放前面。
第三题:用最少数量的箭引爆气球
好抽象的题目!
对气球排序,以起始位置进行排序,然后遍历气球,检查重叠气球中右边界的最小值之前的区间一定需要一支箭,箭的位置就是重叠边界右端最小值