首页 > 编程语言 >代码随想录算法训练营第二十五天|134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列

代码随想录算法训练营第二十五天|134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列

时间:2024-08-02 08:56:19浏览次数:20  
标签:return people int 随想录 List 找零 柠檬水 糖果

写代码的第二十五天
继续贪心!!gogogo!

134. 加油站

思路

贪心算法总让我有种脑子知道每次怎么计算,但是写不出来,也想不出贪心贪在哪里了,就只是觉得应该这么做。。。。。
本题中大家可以按照自己的计算方法一步一步模拟一下这个过程,然后会发现其实每次都是要计算每站剩余的油量,统计每一次的剩余油量然后累加计算,如果这个累加油量小于零那么就证明这个点之前的所有的点包括这个点都不满足走一圈的条件,从这个点之后的点继续向后遍历。
错误第一版:测试用例没通过,cursum在发现小于零的时候应该归零,因为从新开始的点开始遍历,累加和也要重新开始。

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        start = 0
        cursum = 0
        for i in range(len(gas)):
            cursum += (gas[i]-cost[i])
            if cursum < 0:
                start = i + 1
        if cursum < 0:
            return -1
        return start

正确代码

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        start = 0
        cursum = 0
        totalsum = 0
        for i in range(len(gas)):
            cursum += (gas[i]-cost[i])
            totalsum += (gas[i]-cost[i])
            if cursum < 0:
                start = i + 1
                cursum = 0
        if totalsum < 0:
            return -1
        return start

135. 分发糖果

思路

本题的要求是每个小孩最少一块糖,相邻的小孩分高的糖要更多,问怎么能用最少的糖果满足这个条件。可以分成两部分解决这个问题,从左向右和从右向左两个方向分别计算。初始化所有孩子的糖果都为1.
从左向右:如果右侧比左侧的分高,那么右侧应该在左侧的糖果的基础上加一;如果右侧小于等于左侧,那么右侧糖果数为1.
从右向左:在上述从左向右的基础上就是已经满足了右侧大于左侧的情况的糖果数量,现在要比较左侧比右侧大的时候的糖果数量,在上述糖果数量的基础上,如果左侧比右侧的糖果数量大,那么要在右侧糖果的基础上加一,需要注意一个问题如果这个时候的加一之后的值小于上一步计算之后的值,那么我们要保留最大的那个(只有保留最大的那个,才能满足左到右和右到左两部分);如果左侧小于等于右侧的糖果数量,此时不能设置左侧为1,如果设置为1,那么之前从左向右的计算就没有意义了,所以应该保持之前的到的值不变。
正确代码

class Solution:
    def candy(self, ratings: List[int]) -> int:
        candy = [1] * len(ratings)
        for i in range(len(ratings)):
            if i > 0 and ratings[i] > ratings[i-1]:
                candy[i] = candy[i-1] + 1
        for i in range(len(ratings)-2,-1,-1):
            if ratings[i] > ratings[i+1]:
                candy[i] = max(candy[i+1] + 1,candy[i])
        return sum(candy)

860.柠檬水找零

思路

题意只有5 10 20这三种情况的钱,所以根据这三种情况进行找零分析:
1、收到5的时候:直接收下,不用找零;
2、收到10的时候:如果有5,那么正常找零;如果没有5那么无法找零,失败;
3、收到20的时候:如果有一张10,一张5,那么正常找零;如果没有10,但是有三张5,也可以正常找零;如果不满足上面俩条件,那么失败。
(为什么要先判断有没有10,因为对于10来说只能对20进行找零,其他的时候没用,而5可以对10也可以对20找零,用处更广。)
正确代码

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        five = 0
        ten = 0
        for i in range(len(bills)):
            if bills[i] == 5:
                five += 1
            elif bills[i] == 10:
                if five:
                    five -= 1
                    ten += 1
                else:
                    return False
            elif bills[i] == 20:
                if ten and five:
                    ten -= 1
                    five -= 1
                elif five >= 3:
                    five -= 3
                else:
                    return False
        return True

406.根据身高重建队列

思路

本题有两个维度h和k,首先要决定 先排哪个维度?
如果先排k:以这个为例people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]],按照从小到大的顺序people=[[7,0].[5,0],[7,1],[6,1],[5,2],[4,4]],在这个顺序的基础上排h,然后会发现排完k对排h没有任何帮助,还是要手动一点一点调(动手写一下就明白了,这次排序没起到任何作用),没有任何可以插入的规律。
如果先排h:以这个为例people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]],按照从大到小的顺序(因为二维数组中的数据代表的就是前面有k个大于等于h的数据,所以从大到小排更方便)people=[[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]],在这个顺序的基础上排k,此时70和71都满足题条件,61不满足条件,但是按照我们的排序顺序将61插入到下标为1的位置就可以了,因为h的顺序是已经排完的,所以是在有序的基础上只要将前面比他大于等于的数字满足k就行,排序之后的顺序是70 61 71,在看50也不满足所以将50插入到下标为0的点就行了,排序之后的顺序是50 70 61 71,再看52,将其插入到下标为2的位置就行了,排序之后的顺序是50 60 52 61 71,最后是44也不满足条件,将44插入到下标为4的位置即可,50 60 52 61 44 71,与最后的输出结果一致。
正确代码:这个题对我来说代码难得部分在people = sorted(people, key=lambda x: (-x[0], x[1])),以及queue.insert(position,people[i])。语法要记住。
解释一下为什么是position = people[i][1],我们是按照下标位置插入的,看上面写的思路中比如44也不满足条件,将44插入到下标为4的位置即可,我们是按照k的位置进行插入的,所以i代表的是在people这个数组中的哪个数组需要插入进queue(比如【4,4】),1代表的是people数组中第i位数组中的下标为1的数字,这个数字才是我们要在queue中插入的位置(【4,4】中的第二个4)。

class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people = sorted(people, key=lambda x: (-x[0], x[1]))
        queue = []
        for i in range(len(people)):
            position = people[i][1]
            queue.insert(position,people[i])
        return queue

标签:return,people,int,随想录,List,找零,柠檬水,糖果
From: https://blog.csdn.net/MYSTICSHUN/article/details/140812131

相关文章

  • 代码随想录算法训练营第二十六天|452. 用最少数量的箭引爆气球、435. 无重叠区间、763
    写代码的第二十六天继续贪心贪心!!!452.用最少数量的箭引爆气球思路最少的弓箭引爆气球,那么就是要看有没有重复覆盖的区域,如果有的话,那么一个弓箭就能引爆重复区域的气球,所以本题就是要看有多少气球是重复的,如果重复就用一根弓箭,如果不重复就加一。解决问题1:如何判断是否......
  • 代码随想录算法训练营第二十七天| 56. 合并区间、738.单调递增的数字
    写代码的第二十七天最后一天贪心!!!加油呀!!!56.合并区间思路这道题本质上和昨天的两道题是几乎完全一致的,都是判断重叠区间,只不过昨天的射箭那道题是统计有多少重叠区间,无重叠区间那道题是找到重叠区间然后删除,这道题是找到重叠区间然后合并。解决问题1:如何对重叠区间进行......
  • 「代码随想录算法训练营」第二十六天 | 贪心算法 part4
    452.用最少数量的箭引爆气球题目链接:https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/题目难度:中等文章讲解:https://programmercarl.com/0452.用最少数量的箭引爆气球.html视频讲解:https://www.bilibili.com/video/BV1SA41167xe题目状态:有点思路......
  • 「代码随想录算法训练营」第二十五天 | 贪心算法 part3
    134.加油站题目链接:https://leetcode.cn/problems/gas-station/题目难度:中等文章讲解:https://programmercarl.com/0134.加油站.html视频讲解:https://www.bilibili.com/video/BV1jA411r7WX题目状态:没有思路,学习题解思路一:全局最优解首先将所有路径的加油量和耗油量加一起......
  • 代码随想录Day2
    209.长度最小的子数组给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的子数组$[nums_l,nums_{l+1},...,nums_{r-1},nums_r]$,并返回其长度。如果不存在符合条件的子数组,返回0。示例1:输入:target=7,nums=......
  • 代码随想录算法训练营第56天 | 广搜和深搜应用
    110.字符串接龙https://kamacoder.com/problempage.php?pid=1183代码随想录https://www.programmercarl.com/kamacoder/0110.字符串接龙.html#思路105.有向图的完全可达性https://kamacoder.com/problempage.php?pid=1177代码随想录https://www.programmercarl.com/kamaco......
  • 代码随想录算法训练营day01|704. 二分查找,27. 移除元素,977.有序数组的平方
    704.二分查找题目链接:https://leetcode.cn/problems/binary-search/description/本人代码:classSolution{public:intsearch(vector<int>&nums,inttarget){intlow=0,high=nums.size()-1;//此处分情况讨论returnsearchTarget(nums,low,high,tar......
  • 代码随想录day16 || 513 树左下角值,112 路径之和,116 中序后序遍历构造二叉树
    切片传递问题question:什么情况下传递切片,什么情况下传递切片指针,为什么有时候会修改原始副本,有时候又不会呢?typesli[]intfuncmain(){ slice:=[]int{1} fmt.Printf("slice:%p\n",slice) change1(slice) fmt.Println("=================================") s2:=......
  • 代码随想录Day1
    704.二分查找给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且下标为4示例2:......
  • # 代码随想录二刷(哈希表)
    代码随想录二刷(哈希表)三数之和思路反正对于我来说是真的难想出来。若这道题还是采用哈希表的思路去做,非常麻烦,并且还要考虑去重的操作。所以这道题其实用双指针,是更方便的。具体程序如下:classSolution:defthreeSum(self,nums:List[int])->List[List[int]]:......