• 代码随想录算法训练营第三十四天| LeetCode1005. K 次取反后最大化的数组和、LeetCode134. 加油站、LeetCode135. 分发糖果


    一、LeetCode1005. K 次取反后最大化的数组和

            1:题目描述(1005. K 次取反后最大化的数组和

            给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

    • 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

            重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

            以这种方式修改数组后,返回数组 可能的最大和 。

            2:解题思路

    1. class Solution:
    2. def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
    3. # 有负数,最小的负数先取相反数,这样得到的和是最大的
    4. # 有正数,最小的正数先取相反数,这样得到的和也是最大的
    5. # 对nums按绝对值从大到小进行排序,这样绝对值最小的值就在最后面
    6. nums = sorted(nums, key=abs, reverse=True)
    7. for i in range(len(nums)):
    8. # 遍历nums,当k>0并且nums[i]小于0,说明此时的负数是最小的
    9. if k > 0 and nums[i] < 0:
    10. # 取其相反数
    11. nums[i] = -nums[i]
    12. # k减1
    13. k -= 1
    14. # 当遍历完nums后,k任然大于0
    15. # 此时nums中的数为非负数,最小的值在后面
    16. # 此时只需要将最后面的元素进行剩余k次的取相反数,就可得到最大和
    17. if k > 0:
    18. nums[-1] *= (-1)**k # (-1)**k中的-1需要用括号扩起来
    19. return sum(nums)

    二、LeetCode134. 加油站

            1:题目描述(134. 加油站)

            在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

            你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

            给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

            2:解题思路

    1. class Solution:
    2. def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
    3. # 暴力法---超时了
    4. # # 以gas的每个点作为起点,看是否能绕行一周
    5. # for i in range(len(gas)):
    6. # rest = gas[i] - cost[i] # 记录从i到i+1所剩余的油量
    7. # index = (i+1)%len(gas) # 记录下一个到到达的加油站
    8. # while rest > 0 and index != i:
    9. # rest += gas[index] - cost[index] # 叠加剩余的油量
    10. # index = (index+1)%len(gas) # 下一个加油站
    11. # # 如果跑完一圈剩余的油量大于等于0,则存在解
    12. # if rest >= 0 and index == i:
    13. # return i
    14. # # 遍历完所有的起点,都没有符合要求的,就返回-1
    15. # return -1
    16. start = 0 # 加油站的起始位置
    17. curSum = 0
    18. totalSum = 0 # 统计剩余的油量
    19. # 从第0个加油站开始计算剩余油量
    20. for i in range(len(gas)):
    21. curSum += gas[i] - cost[i] # 统计剩余油量
    22. totalSum += gas[i] - cost[i] # 统计剩余油量
    23. if curSum < 0:
    24. # 当剩余油量小于0,说明已i之前的站点为起点,就已经不够行使到当前加油站了
    25. curSum = 0 # 重置剩余油量,为0
    26. start = i+1 # 起始位置为下一个加油站
    27. if totalSum < 0:
    28. # 剩余的油量小于0,则不能行使一周
    29. return -1
    30. # 最后剩余的油量大于等于0,则从start为起点可以绕行一周
    31. return start

    三、LeetCode135. 分发糖果

            1:题目描述(135. 分发糖果

            n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

            你需要按照以下要求,给这些孩子分发糖果:

    • 每个孩子至少分配到 1 个糖果。
    • 相邻两个孩子评分更高的孩子会获得更多的糖果。

            请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

            2:解题思路

    1. class Solution:
    2. def candy(self, ratings: List[int]) -> int:
    3. candyVec = [1] * len(ratings) # 先定义每个孩子分配到1个糖果
    4. # 从左向右遍历,若当前孩子的评分高于前一个孩子时,当前孩子就比前一个孩子多分配一个糖果
    5. for i in range(1,len(ratings)):
    6. if ratings[i] > ratings[i-1]:
    7. candyVec[i] = candyVec[i-1] + 1
    8. # 从右向左遍历,若当前孩子的评分高于后面一个孩子,当前孩子需要比后一个孩子多分配一个糖果
    9. for j in range(len(ratings)-2, -1, -1):
    10. if ratings[j] > ratings[j+1]:
    11. # 因为相邻两个孩子评分更高的孩子获得更多的糖果
    12. # 所以当前孩子所获得的糖果需要在当前已获得的糖果(之前比较右孩子大于左孩子得到的糖果数量)和比后一个孩子多分配一个糖果中取最大值
    13. # 只有取最大的才能既保持对左边candyVec[i - 1]的糖果多,也比右边candyVec[i + 1]的糖果多
    14. candyVec[j] = max(candyVec[j], candyVec[j+1]+1)
    15. return sum(candyVec)
  • 相关阅读:
    排序:最佳归并树(优化外部排序中对磁盘的读写次数)
    前端内存泄漏的场景
    springboot+Vue.js+Elementui大学生就业信息网站管理系统java项目推荐
    dreamweaver作业静态HTML网页设计模板——迪士尼影视电影(6页)带音乐
    15:00面试,15:08就出来了,问的问题有点变态。。。
    QWidget核心属性(二)
    制糖行业脱色技术A30MP树脂材料
    Hadoop大数据开发__HBase分布式集群安装部署
    【愚公系列】2022年09月 MAUI框架-MAUI项目的创建
    centos7安装mariadb
  • 原文地址:https://blog.csdn.net/weixin_48323589/article/details/127864664