leetcode:吃苹果的最大数目(最小堆+贪心)

leetcode:吃苹果的最大数目(最小堆+贪心)
我的思路:
给活着的苹果记录下来,每天更新
很不幸,超时了

我的初代暴力代码:

class Solution:
    def eatenApples(self, apples: List[int], days: List[int]) -> int:
        # 每天都吃最快要过期的苹果?
        cur = []
        ans = 0
        maxn = 0

        for i in range(len(apples)):
            maxn = max(maxn, i + days[i])

        for i in range(maxn):
            print(cur)
            # 每过一天剩余日期减1
            new_cur = []
            for j in range(len(cur)):
                cur[j][1] -= 1
                if cur[j][1] != 0:
                    new_cur.append(cur[j])
            cur = copy.deepcopy(new_cur)
            # 加入当天苹果
            if i < len(apples) and days[i] != 0:
                cur.append([apples[i], days[i]])
            # 根据快过期的日子排序
            cur.sort(key = lambda k: k[1])
            # 吃一个最快过期的
            if len(cur) > 0:
                cur[0][0] -= 1
                ans += 1
                if cur[0][0] == 0:
                    del cur[0]
            if i > len(apples) and len(cur) == 0:
                break
        return ans

尝试优化:
体会一下最小堆
我擦!还是超时!

class Appleday:
    def __init__(self, num:int, day:int) -> None:
        '''
        idx, idy是素数所在的位置 
        x, y对应idx和idy的素数值
        '''
        self.num = num
        self.day = day
    
    #定义优先队列的排序方法
    #类名要加""
    def __lt__(self, other: "Appleday") -> bool:
        return self.day < other.day



class Solution:
    def eatenApples(self, apples: List[int], days: List[int]) -> int:
        # 每天都吃最快要过期的苹果?
        cur = []
        ans = 0
        maxn = 0

        for i in range(len(apples)):
            maxn = max(maxn, i + days[i])

        for i in range(maxn):
            print(cur)
            # 每过一天剩余日期减1
            new_cur = []
            for j in range(len(cur)):
                cur[j].day -= 1
                if cur[j].day != 0:
                    new_cur.append(cur[j])
            cur = copy.deepcopy(new_cur)
            # 加入当天苹果
            if i < len(apples) and days[i] != 0:
                cur.append(Appleday(apples[i], days[i]))
            heapq.heapify(cur)
            # 吃一个最快过期的
            if len(cur) > 0:
                cur[0].num -= 1
                ans += 1
                if cur[0].num == 0:
                    del cur[0]
            if i > len(apples) and len(cur) == 0:
                break
        return ans

看答案吧:
答案居然是贪心+优先队列(其实我这两个都想到但就是没写出来555)

啊!!!答案思路和我一样!

leetcode:吃苹果的最大数目(最小堆+贪心)
但是答案要分成两个阶段处理:有苹果生成和空耗时间
行吧,我离答案还有一些差距!
但起码思想正确!

正确答案:


# 若有多元组, heapq按第一个元素进行排列
class Solution:
    def eatenApples(self, apples: List[int], days: List[int]) -> int:
        # 每天都吃最快要过期的苹果?-> 贪心
        # 用优先队列找出最快要过期的苹果

        ans = 0
        pq = []
        i = 0
        
        # 当有苹果的时候
        while i < len(apples):
            # 清除过期的苹果
            while pq and pq[0][0] <= i:
                heappop(pq)
            # 加入有效的苹果
            if apples[i]:
                heappush(pq, [i + days[i], apples[i]])
            # 吃最快过期的苹果
            if pq:
                pq[0][1] -= 1
                if pq[0][1] == 0:
                    heappop(pq)
                ans += 1
            i += 1
        
        # 当没有新的苹果的时候
        while pq:
            # 清楚过期的苹果
            while pq and pq[0][0] <= i:
                heappop(pq)
            # 没有库存
            if len(pq) == 0:
                break
            # 核心逻辑
            # 先吃最先过期的那一坨苹果
            p = heappop(pq)
            # 能吃的最大数量
            num = min(p[0] - i, p[1])
            ans += num
            i += num


        return ans

总结:
讲真正确答案的每一个逻辑我都考虑过
就是没想到要分开写,害!

上一篇:C语言练习题 :猴子吃桃程序


下一篇:LeetCode刷题日记2021-12-24/1705. 吃苹果的最大数目-贪心&优先队列