leetcode 176 周賽

5340. 統計有序矩陣中的負數

題意:

統計二維矩陣中非負個數。

代碼:

class Solution:
    def countNegatives(self, grid: List[List[int]]) -> int:
        ans =0
        for row in grid:
            for num in row:
                if num < 0: ans+=1
        return ans

5341. 最後 K 個數的乘積

題意:

實現一個類兩個函數,對一個數組具有兩個操作:

  • 在一個數組末尾添加元素
  • 求數組末尾k個元素的乘積

思路:

明顯第一個操作已經是O(1)沒辦法優化,第二個操作如果是求前k個乘積就很明顯預處理出前綴和,然後O(1),同時有了前綴和pre(i)也可以O(1)求得任意區間的和 sum(i,j)

sum(i,j)= pre(j) - pre(i-1)

那麼借用前綴和思想,我們在第一個操作裏隨便得到前綴積,那後k個乘積很容易想到乘法逆運算除法O(1)可以求得區間的積,自然後k個乘積也很容易。
mutil(i,j) = pre(j) / pre(i-1)

但要注意一個細節,插入元素爲0的時候,需要特殊處理,如果問的後k個元素裏面有0,直接返回0即可。

這樣兩個操作都是O(1)

代碼:

class ProductOfNumbers:

    def __init__(self):
        self.data = [1]

    def add(self, num: int) -> None:
        if num == 0:
             self.data = [1]
        else :
            self.data.append(self.data[-1] * num)

    def getProduct(self, k: int) -> int:
        if k>= len(self.data) :
             return 0
        else : 
            return int(self.data[-1] / self.data[-1-k])

5342. 最多可以參加的會議數目

題意:

題面很清晰,就是儘量選擇滿足條件的區間。

思路:

明顯的貪心,分析一下原則:即在當前滿足條件的所有任務裏,爲了後面儘量選擇更多一點,就是選擇結束日期最早的那個任務。

具體怎麼實現這個原則: 先對所有任務的起始時間排序,然後用一個最小堆的數據結構維護當前滿足條件(任務起始天數小於等於當前日期)的所有任務的結束日期。

然後以日期爲軸枚舉每天選擇滿足條件裏結束日期最小的任務,順帶更新一下這個最小堆

代碼:

class Solution:
    def maxEvents(self, events) -> int:
        events = sorted(events, key =lambda x : x[0])
        ans = 0
        small_headp = []
        import heapq
        i ,day , n = 0 ,events[0][0], len(events)
        while True :
            while i<n and events[i][0] <= day :
                heapq.heappush(small_headp , events[i][1])
                i +=1
            while len(small_headp) >0 and small_headp[0] < day:
                heapq.heappop(small_headp)
            if len(small_headp) >0:
                ans += 1
                heapq.heappop(small_headp)
            day +=1
            if i ==n and len(small_headp) == 0: break
        return ans

5343. 多次求和構造目標數組

題意

給一個target數組,問能不能從全是[1,1,1,…,1]的數組通過重複替換某個位置的值爲當前數組之和逐步變換而來。

解題思路

開始先嚐試暴力廣搜,TLE,然後嘗試正向找一下的規律進行剪枝,正向並不能判斷出每一次正確位置的規律…

但反過來:每一次選擇改變的那個位置會變成當前的最大值, 也就是我們從target每次都是從最大值推過來的…於是反向遞推一下就好。

然後這裏找當前數組裏最大值,可以用最大堆,或者bisect.insort()進行log級別優化。

圖片.png

代碼

heapq最小堆取相反數變成最大堆。

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        import heapq
        que = []
        total = 0
        for num in target:
            heapq.heappush(que,(-num))
            total +=num
        while True:
            max_value = heapq.heappop(que)
            max_value *= -1
            if max_value == 1: return True
            total -= max_value
            max_value -= total
            total += max_value
            if max_value <=0:  return False
            heapq.heappush(que, (-max_value)) 

利用bisect.insort也可以實現了找最大值時Log的優化!

class Solution:
    def isPossible(self, target) -> bool:
        total = sum(target)
        if total == len(target) : return True
        target = sorted(target)
        while True:
            num = target.pop()
            if num == 1: return True
            total -= num
            num -= total
            if num <0 :return False
            total += num
            import bisect
            bisect.insort(target, num)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章