860.柠檬酸找零 文章:13. 柠檬水找零
题目:860. 柠檬水找零
【思路】
有三种情况:
1.账单是5,直接收下
2.账单是10,消耗一个5,增加一个10
3.账单是20,优先消耗一个10和一个5, 如果不够,再消耗三个5
分析得出:只有10和5是可以被交易出去的,而10的使用频率比5低。
局部最优:遇到账单20,优先消耗10,完成本次找零。
全局最优:完成全部账单的找零。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public boolean lemonadeChange (int [] bills) { int five = 0 ; int ten = 0 ; for (int i : bills){ if (i == 5 ){ five++; }else if (i == 10 ){ five--; ten++; }else if (i == 20 ){ if (ten >0 ){ ten--; five--; }else { five -= 3 ; } } if (ten < 0 || five <0 ){ return false ; } } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 func lemonadeChange (bills []int ) bool { ten,five :=0 ,0 for _,i:=range bills{ if i == 5 { five++ }else if i == 10 { ten++ five-- }else if i == 20 { if ten >0 &&five >0 { ten-- five-- }else { five -=3 } } if ten <0 || five <0 { return false } } return true }
406.根据身高重建队列 文章:14. 根据身高重建队列
题目:406. 根据身高重建队列
【思路】
题目给出了两个维度:h身高、k属性
那么我们就需要在这两个维度上面选一个优先进行排序。
k属性的话,会有很多问题,因此我们确定以h属性为维度。
h属性:身高一定是按照大到小来排的,身高相同的话k小的在前面。
局部优先:优先按身高高的people的k来插入,插入操作后的people满足队列属性。
全局最优:最后都做完插入操作,整个队列满足题目队列属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int [][] reconstructQueue(int [][] people) { Arrays.sort(people,(a,b)->{ if (a[0 ] == b[0 ])return a[1 ] - b[1 ]; return b[0 ]-a[0 ]; }); LinkedList<int []> que = new LinkedList <>(); for (int [] p: people){ que.add(p[1 ],p); } return que.toArray(new int [people.length][]); } }
没看懂这里:
1 2 3 4 for i,p:=range people{ copy (people[p[1 ]+1 :i+1 ],people[p[1 ]:i+1 ]) people[p[1 ]] =p }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 func reconstructQueue (people [][]int ) [][]int { sort.Slice(people,func (i,j int ) bool { if people[i][0 ] == people[j][0 ]{ return people[i][1 ] < people[j][1 ] }else { return people[i][0 ] > people[j][0 ] } }) for i,p:=range people{ copy (people[p[1 ]+1 :i+1 ],people[p[1 ]:i+1 ]) people[p[1 ]] =p } return people }
452.用最少数量的箭引爆气球 文章:17. 用最少数量的箭引爆气球
题目:452. 用最少数量的箭引爆气球
【思路】
贪心
局部最优:当气球出现重叠,一起射的时候所用的弓箭最少。全局最优:把所有气球射爆所用的弓箭最少。
排序+检查区间是否重叠,重叠的话更新最右边界,不重叠的话count+1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int findMinArrowShots (int [][] points) { Arrays.sort(points,(a,b)->Integer.compare(a[0 ],b[0 ])); int count = 1 ; for (int 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; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 func findMinArrowShots (points [][]int ) int { sort.Slice(points,func (i,j int ) bool { return points[i][0 ]<points[j][0 ] }) count:= 1 for i:=1 ;i < len (points);i++{ if points[i][0 ] > points[i-1 ][1 ]{ count++ }else { points[i][1 ] = min(points[i-1 ][1 ],points[i][1 ]) } } return count } func min (a,b int ) int { if a>b { return b } return a }
【算法总结】
柠檬水找零:贪心,优先消耗使用频率最低的零钱
根据身高重建队列:贪心,先按其中一个属性排序,然后再通过另一个属性插入队列。
最小数量的箭射击气球:贪心,排序,查询重叠区间并更新最右区间(会出现气球最右范围变小的情况。
【语言总结】
老生常谈的不懂自定义排序:
1 2 3 4 Arrays.sort(people,(a,b)->{ if (a[0 ] == b[0 ])return a[1 ] - b[1 ]; return b[0 ]-a[0 ]; });
1 Arrays.sort(points,(a,b)->Integer.compare(a[0 ],b[0 ]));
1 2 3 4 5 6 7 sort.Slice(people,func (i,j int ) bool { if people[i][0 ] == people[j][0 ]{ return people[i][1 ] < people[j][1 ] }else { return people[i][0 ] > people[j][0 ] } })
1 2 3 sort.Slice(points,func (i,j int ) bool { return points[i][0 ]<points[j][0 ] })