今日题目:
860. 柠檬水找零
406. 根据身高重建队列
452. 用最少数量的箭引爆气球
今日总结
学会处理两种维度的题目。重叠区间的入门。
860. 柠檬水找零
要点
- 简单题。关键点在于遇到20块的时候要优先使用10块来找零,因为这是10块的唯一功能。
- 复习一下switch语句。
代码:
func lemonadeChange(bills []int) bool {
leftCoin := make(map[int]int, 2)
for i := 0; i<len(bills);i++{
switch bills[i]{
case 5:
leftCoin[5]++
case 10:
if leftCoin[5] > 0{
leftCoin[5]--
leftCoin[10]++
} else {
return false
}
case 20:
if leftCoin[10] > 0 && leftCoin[5] > 0{
leftCoin[5]--
leftCoin[10]--
} else if leftCoin[5] >= 3 {
leftCoin[5] -=3
} else {
return false
}
}
}
return true
}
406. 根据身高重建队列
要点:
- 类似于前一天的发糖果的题目,需要考虑两个维度的条件。思想上同样是先处理一边再处理另一边。
- 这道题的核心思想就是先按照身高h从大到小排序,为什么是从小到大?因为在之后的插入过程中,将身高矮的人插在身高高的人之前并不会影响身高高的人的合法性。
- 之后按照k进行插入。怎么按照k进行插入?插入位置直接就是下标等于k的位置。由于2,在将后续身高矮的角色向前插入时,这个角色前面的序列都是比他身高高的,所以我们只需要前面满足有k个身高大于此角色的人即可。
- 这题在编写上的难点在于怎么实现按照h进行排序,golang的排序记得使用sort函数。
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] // 当身高相同时,将K按照从小到大排序
}
return people[i][0] > people[j][0] // 身高按照由大到小的顺序来排
})
// 再按照K进行插入排序,优先插入K小的
for i, p := range people {
copy(people[p[1]+1 : i+1], people[p[1] : i+1]) // 空出一个位置
people[p[1]] = p
}
return people
}
452. 用最少数量的箭引爆气球
要点:
- 贪心中的重叠区间问题。要点在于怎么表示重叠的区间。
- 先排序,将在y轴上不同分布的气球按照一定顺序排列以寻找规律。
- 这道题的要点在于,对于多个重叠的气球,应该寻找最小的右边界来限定重叠区域。一旦有气球的左边界大于这个最小的右边界,那么就意味着需要额外使用一支箭。
func findMinArrowShots(points [][]int) int {
res := 1
sort.Slice(points, func (i, j int) bool{
return points[i][0] < points[j][0] //按照左边界排序
})
for i := 1;i <len(points);i++{
if points[i-1][1] < points[i][0] { //前一个气球的右边界小于第二个的左边界意味着绝对不重合
res++
} else {
points[i][1] = min(points[i-1][1], points[i][1]) //如果气球重叠,那么使用最小右边界来限定重叠的范围
}
}
return res
}
func min(a, b int) int {
if a > b{
return b
}
return a
}