代码随想录 day35 第八章 贪心算法 part04

●  860.柠檬水找零

●  406.根据身高重建队列

●  452. 用最少数量的箭引爆气球

1. 柠檬水找零

关联 leetcode 860.柠檬水找零

  • 思路

    • 使用金额的三种情况
      • 情况一 :
        • 账单是5, 直接收下
      • 情况二 :
        • 账单是10, 消耗一个5, 收获一个10
      • 情况三 :
        • 账单是20, 优先消耗一个10和一个5,如果不够,再消耗三个5
    • 贪心[ 针对情况三 ]
      • 局部
        • 优先消耗 10元, 5元的更万能
      • 全局
        • 完成账单清零
  • 题解

    func lemonadeChange(bills []int) bool {
    	if bills[0] > 5 || len(bills) < 1 {
    		return false
    	}
    	restMoney := make(map[int]int) //剩余零钱, 可以用数字提升效率, 这里用map看的更清楚
    
    	for _, b := range bills {
    		switch b {
    		case 5:
    			restMoney[5] += 1
    		case 10:
    			restMoney[5] -= 1
    			if restMoney[5] < 0 {
    				return false
    			}
    			restMoney[10] += 1
    		case 20:
    			if restMoney[10] > 0 {
    				restMoney[10] -= 1
    				restMoney[5] -= 1
    			} else {
    				restMoney[5] -= 3
    			}
    			if restMoney[5] < 0 {
    				return false
    			}
    			restMoney[20] += 1 // 这一步可以不要, 20不会用来找零
    		}
    	}
    
    	return true
    }
    
    

2. 根据身高重建队列

关联 leetcode 406.根据身高重建队列

  • 思路

    • 两个指标出现时, 每次解决一个指标
      • 本题的 k, h 每次贪一个指标
      • 本题来说
        • 身高是绝对序列, 唯一有序
        • 前面的人数是可能唯一有序
        • 选择 身高 作为第一次遍历指标
    • 贪心
      • 前提 已经按照身高降序排序,
      • 再按照 k 值升序
        • k小的前面人更少, 所以这个人在更前面的位置
      • 局部最优
        • 优先按身高高的people的k来插入。插入操作过后的people满足队列属性
      • 全局最优
        • 最后都做完插入操作,整个队列满足题目队列属性
  • 题解

    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]
    		}
    		return people[i][0] > people[j][0]
    	})
    	rets := make([][]int, len(people))
    	for i := 0; i < len(people); i++ {
    		insertVal := people[i]
    		insertIdx := people[i][1]
    
    		//插入
    		if rets[insertIdx] == nil {
    			rets[insertIdx] = insertVal
    			continue
    		}
    		before := rets[:insertIdx]
    		after := make([][]int, len(rets[insertIdx:]))
    		copy(after, rets[insertIdx:])
    		before = append(before, insertVal)
    		rets = append(before, after...)
    
    	}
    	return rets[:len(people)]
    }
    

3. 用最少数量的箭引爆气球

关联 leetcode 452. 用最少数量的箭引爆气球

  • 思路

    • 贪心
      • 局部最优
        • 重叠最多的气球
      • 全局最优
        • 最少的箭
    • 排序
      • 选择左/右边界来排序
        • 算重叠
          • 当前 左边界 与 前一个 右边界关系
  • 题解

    func findMinArrowShots(points [][]int) int {
    	if len(points) < 2 {
    		return len(points)
    	}
    
    	sort.Slice(points, func(i, j int) bool {
    		return points[i][0] < points[j][0]
    	})
    
    	res := 1 //至少需要一只箭
    
    	for i := 1; i < len(points); i++ { // i从1开始, 要与左边的相比, 至少是从左开始数第二个
    		if points[i][0] > points[i-1][1] { // 当前的左边 比 前一个的右边大
    			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 a
    	}
    	return b
    }
    

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值