leetcode 第 176 場周賽 - 代碼和解釋 - python

https://leetcode-cn.com/conte...python

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

https://leetcode-cn.com/conte...算法

class Solution:
    def countNegatives(self, grid: List[List[int]]) -> int:
        n = len(grid)
        m = len(grid[0])
        c = 0
        for i in range(n-1, -1, -1):
            if grid[i][-1] >= 0: break
            for j in range(m-1, -1, -1):
                if grid[i][j] < 0:
                    c += 1
                else:
                    break
        return c

第二題 5341.最後 K 個數的乘積

https://leetcode-cn.com/conte...數組

第一可能查詢的次數不少,區間也可能很大,若是每次查詢都現算可能超時。可是每一個數字都不大。app

這時候就考慮不存數字自己,而是存連乘後的結果。例如輸入的 a b c d。則存的是 a,a×b,a×b×c,a×b×c×d。這樣。若是查詢最後兩個數相乘,就是倒數第一除以倒數第三就是 (a×b×c×d)/ (a×b)= c × d。這樣每次查詢只須要作一次除法,每次輸入只須要作一次乘法。優化

用 python 的一個優點是,不用考慮整數溢出的問題。code

這裏還有一個問題沒有處理,就是 0。當時沒考慮到,可是樣例救了我,跑樣例除了除零錯誤。排序

對於 0 的思路是,每次遇到 0 直接清空列表,由於前面是啥都沒用了,只要超過 0 的位置,前面的都是 0 了。遞歸

而相應的查詢的地方,長度超過列表長度,直接返回 0,由於面前確定是遇到 0 了。隊列

再一個爲了代碼方便,直接列表第一個默認自帶一個 1。ip

class ProductOfNumbers:

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

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

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


# Your ProductOfNumbers object will be instantiated and called as such:
# obj = ProductOfNumbers()
# obj.add(num)
# param_2 = obj.getProduct(k)

第三題 5342.最多能夠參加的會議數目

https://leetcode-cn.com/conte...

貪心算法。使用優先隊列,先從最小的一天開始安排。

策略是按照開始日期分組,每一組(也就是天天)只取一個結束時間最先的(也就是會議長度最短的)。而後這把一組其餘的全部其餘會議的開始時間修改成下一天,放入優先隊列排序。

大體是在這樣,可是能夠有一些小的優化,好比結束日期就是當前處理的一天的會議就能夠直接安排上。由於這個會議安排上必定不會影響後面別的會。

總體的貪心策略就是儘量安排這一天開一個結束日期最先的會。

import queue

class Solution:
    def maxEvents(self, events: List[List[int]]) -> int:
        q = queue.PriorityQueue()
        for e in events:
            q.put(e)
        e = q.get()
        cnt = 1
        cd = e[0] + 1
        while not q.empty():
            e = q.get()
            if e[0] == cd:
                if e[1] >= cd:
                    cd += 1
                    cnt += 1
            elif e[0] > cd:
                cd = e[0] + 1
                cnt += 1
            else: # e[0] < cd
                if e[1] == cd:
                    cd += 1
                    cnt += 1
                if e[1] > cd:
                    e[0] = cd
                    q.put(e)
        return cnt

第四題 5343.屢次求和構造目標數組

https://leetcode-cn.com/conte...

這道題目找到規律後實現很簡單。

由於兩個步驟是交替進行的。因此當前狀態中最大的一個數就必然是 x。根據當前狀態能推出上一步的狀態。

而後就能夠推出它被設成 x 以前的值。就是 當前的 x -(當前數組和 - 當前的 x)

而後遞歸調用。

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        while True:
            cx = max(target)
            if cx == 1:
                return True
            idx = target.index(cx)
            s = sum(target)
            lv = cx - (s - cx)
            #print(lv)
            if lv < 1:
                return False
            target[idx] = lv
            #print(target)

歡迎來個人博客: https://codeplot.top/
個人博客刷題分類:https://codeplot.top/categories/%E5%88%B7%E9%A2%98/

相關文章
相關標籤/搜索