当前位置:   article > 正文

代码随想录 day34 第八章 贪心算法 part03

代码随想录 day34 第八章 贪心算法 part03

●  1005.K次取反后最大化的数组和

●  134. 加油站

●  135. 分发糖果

1005.K次取反后最大化的数组和

关联 leetcode 1005.K次取反后最大化的数组和

  • 思路

    • 优先对负数取反
      • 优先对绝对值最大的负数取反
    • 贪两次
      1. 先将所有负数取反 ===》全正整数
      2. 将最小的数进行剩下的取反操作
  • 题解

    1. func largestSumAfterKNegations(nums []int, k int) int {
    2. res := 0
    3. // 对数组按绝对值排序: 倒序排列,保证优先处理到的是最大的负数
    4. sort.Slice(nums, func(i, j int) bool {
    5. fi := float64(nums[i])
    6. fj := float64(nums[j])
    7. return math.Abs(fi) > math.Abs(fj)
    8. })
    9. for i := 0; i < len(nums); i++ {
    10. if nums[i] < 0 && k > 0 { //翻转负数
    11. nums[i] = -nums[i]
    12. k--
    13. }
    14. }
    15. // 翻转当前数组最小数剩下的k次
    16. if k%2 == 1 {//
    17. nums[len(nums)-1] *= -1
    18. }
    19. for _, num := range nums {
    20. res += num
    21. }
    22. return res
    23. }

134. 加油站

关联 leetcode 134. 加油站

  • 思路

    • 单向行驶,运动方向固定
    • 先收获当前加油站的汽油,再开向下一个加油站,消耗汽油
    • 如果有解只有唯一解
      • 找到合法解就返回
    • 有效出发点:
      • 获得 汽油数>消耗数
        • 贪最多的
    • 当前累计油耗 < 0:
      • 从该位置的后一个位置出发
  • 题解

    1. func canCompleteCircuit(gas []int, cost []int) int {
    2. res := 0 //默认从第0号索引出发 即 第一个元素
    3. curSum, totalSum := 0, 0
    4. for i := 0; i < len(gas); i++ {
    5. curSum += gas[i] - cost[i]
    6. totalSum += gas[i] - cost[i] //总数直接累计
    7. if curSum < 0 { //当前累计剩余油量小于零, 从改该位置后一个位置开始出发
    8. res = i + 1 //从下一个位置开始
    9. curSum = 0 //curSum重新从0开始累计
    10. }
    11. }
    12. if totalSum < 0 { //总剩余油量totalSum小于0,说明无法环绕一圈
    13. return -1
    14. }
    15. return res
    16. }

135. 分发糖果

关联 leetcode 135. 分发糖果

  • 思路

    • 先确定比较每一个孩子的左边(/右边), 再去比较剩余的那边
      • 如果两边一起比较一定会顾此失彼
    • 贪心
      • 先贪右边, 右边评分更高
        • 从前往后遍历
        • 局部最优
          • 右边评分 > 左边
            • 右边糖果+1
        • 全局最优
          • 相邻孩子:
            • 评分高的右孩子比左孩子有更多糖果
      • 再贪左边
        • 从后往前遍历
        • 局部最优
          • 取 (当前孩子的糖果数量) 和 (右孩子+1) 相比最大的值
        • 全局最优
          • 当前中间评分最高的孩子比他 左边 和 右边 的糖果都多
      • 最终
        • 相邻孩子,评分更高的糖果更多
  • 题解

    1. func candy(ratings []int) int {
    2. res := 0
    3. //初始化分糖数组, 每个值都是1, 保证最小一颗
    4. candyArr := make([]int, len(ratings))
    5. for i := 0; i < len(candyArr); i++ {
    6. candyArr[i] = 1
    7. }
    8. //向右贪
    9. for i := 1; i < len(ratings); i++ {
    10. if ratings[i] > ratings[i-1] {
    11. candyArr[i] = candyArr[i-1] + 1
    12. }
    13. }
    14. //向左贪
    15. for i := len(ratings) - 1; i > 0; i-- {
    16. if ratings[i-1] > ratings[i] {
    17. candyArr[i-1] = max(candyArr[i-1], candyArr[i]+1)
    18. }
    19. }
    20. for _, c := range candyArr {
    21. res += c
    22. }
    23. return res
    24. }
    25. func max(a, b int) int {
    26. if a > b {
    27. return a
    28. }
    29. return b
    30. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/504653
推荐阅读
相关标签
  

闽ICP备14008679号