代码随想录 | Day35 | 2023.09.18 | 贪心04

今日题目:

860. 柠檬水找零
406. 根据身高重建队列
452. 用最少数量的箭引爆气球

今日总结

学会处理两种维度的题目。重叠区间的入门。

860. 柠檬水找零

要点

  1. 简单题。关键点在于遇到20块的时候要优先使用10块来找零,因为这是10块的唯一功能。
  2. 复习一下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. 根据身高重建队列

要点:

  1. 类似于前一天的发糖果的题目,需要考虑两个维度的条件。思想上同样是先处理一边再处理另一边。
  2. 这道题的核心思想就是先按照身高h从大到小排序,为什么是从小到大?因为在之后的插入过程中,将身高矮的人插在身高高的人之前并不会影响身高高的人的合法性。
  3. 之后按照k进行插入。怎么按照k进行插入?插入位置直接就是下标等于k的位置。由于2,在将后续身高矮的角色向前插入时,这个角色前面的序列都是比他身高高的,所以我们只需要前面满足有k个身高大于此角色的人即可。
  4. 这题在编写上的难点在于怎么实现按照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. 用最少数量的箭引爆气球

要点:

  1. 贪心中的重叠区间问题。要点在于怎么表示重叠的区间。
  2. 先排序,将在y轴上不同分布的气球按照一定顺序排列以寻找规律。
  3. 这道题的要点在于,对于多个重叠的气球,应该寻找最小的右边界来限定重叠区域。一旦有气球的左边界大于这个最小的右边界,那么就意味着需要额外使用一支箭。
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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值