程式碼隨想錄演算法訓練營第二十九天| leetcode134. 加油站、leetcode135.分發糖果、leetcode860.檸檬水找零、leetcode406.根據身高重建佇列

小方呀0524發表於2024-11-29

1 leetcode134. 加油站

題目連結:134. 加油站 - 力扣(LeetCode)

文章連結:程式碼隨想錄

影片連結:貪心演算法,得這麼加油才能跑完全程!LeetCode :134.加油站_嗶哩嗶哩_bilibili

思路:其實這道題我有思路了,但是不知道怎麼寫,感覺太暴力了,就是找到花費最小的那個位置且汽油足夠往下走的地方,開始走,然後迴圈,寫的話,我不知道怎麼寫了,只能看影片了

1.1 影片後的思路

嗯,感覺自己把這個想複雜了,沒有想到區域性變數和全域性變數的關係

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

1.2 本題小結

  1. 這道題目就是沒想到用全域性和區域性來統計,就卡住了,不知道怎麼往後面寫能把題目寫出來
  2. 其實貪心主要問題還是區域性最優和全域性最優應該怎麼找,很多時候會忘記這個

2 leetcode135.分發糖果

題目連結:135. 分發糖果 - 力扣(LeetCode)

文章連結:程式碼隨想錄

影片連結:貪心演算法,兩者兼顧很容易顧此失彼!LeetCode:135.分發糖果_嗶哩嗶哩_bilibili

思路:有一種之前做題目,找這個資料是不是擺動數的思路,但是寫的話我不知道怎麼寫

2.1 影片後的思路

寫的時候,自己忘了左邊比右邊大的情況,要對這個數值求最大值的操作,這裡自己寫的時候也出了一點小Bug

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

2.2 本題小結

  1. 每次一到那種倒序遍歷的時候,就很容易超出索引,我的想法,證明練習的題目還是不夠多,需要再加強
  2. 這道題開始真的想的是,如何使用左右兩邊比較,擺動數列的方法來寫,後來發現吧有點行不通

3 leetcode860.檸檬水找零

題目連結:860. 檸檬水找零 - 力扣(LeetCode)

文章連結:程式碼隨想錄

影片連結:貪心演算法,看上去複雜,其實邏輯都是固定的!LeetCode:860.檸檬水找零_嗶哩嗶哩_bilibili

思路:就是區域性找最優,最後如果沒有的話,就進行刪除的操作,程式碼有些複雜,但是實現了

3.1 自己的方法

其實應該可以簡化的,但是思路應該就是這樣的了

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        money_num = []
        for i in range(len(bills)):
            money_num.append(bills[i])
            if bills[i]==10:
                if 5 in money_num:
                    money_num.remove(5)
                else:
                    return False
            elif bills[i] == 20:
                count_file = money_num.count(5)
                if (5 in money_num) and (10 in money_num):
                    money_num.remove(5)
                    money_num.remove(10)
                elif count_file>=3:
                    for i in range(3):
                        money_num.remove(5)
                else:
                    return False
        return True

3.2 影片後的方法

這個方法的程式碼,優點在於統計就可以節省很多空間了,但是思路和我之前的想法其實是一樣的

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

3.3 本題小結

  1. 終於自己寫出來一道題目啦,但是我的思路有一點點複雜
  2. 其實這個用計數統計的方法和用數列的方法是一模一樣的,所以兩者都行的通

4 leetcode406.根據身高重建佇列

題目連結:406. 根據身高重建佇列 - 力扣(LeetCode)

文章連結:程式碼隨想錄

影片連結:貪心演算法,不要兩邊一起貪,會顧此失彼 | LeetCode:406.根據身高重建佇列_嗶哩嗶哩_bilibili

思路:二維的數,瞬間沒思路了,,,,

4.1 影片後的方法

聽了,我明白了為什麼,但是呢,還是不知道怎麼寫,懵逼

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

4.2 本題小結

  1. 題目簡單確實很簡單,但是呢,思路還是不好想,首先就是看到了二維陣列,我就不會了,就不知道怎麼寫了
  2. 一個匿名函式的定義方法key=lambda x:函式
  3. 二維陣列的知識,就有一種增加了一個維度,我就徹底矇蔽了的感覺

5 今日小結

  1. 首先自己嘗試寫出來了一道題目,這是一種進步吧,希望繼續可以保持下去
  2. 二維陣列的題目,時常是搞不清維度就不知道怎麼往後去開發了,但是看了講解以後,我好像就明白了為什麼
  3. 貪心的題目,主要思路就是從區域性最優中找到全域性最優,根據這個思路很多題目就可以做出來

相關文章