1. 程式人生 > 其它 >LeetCode筆記:Weekly Contest 225 比賽記錄

LeetCode筆記:Weekly Contest 225 比賽記錄

技術標籤:leetcode筆記leetcode演算法python

0. 賽後總結

今天總算是又一次把4道題全部搞定了,雖然前兩題錯了三次簡直是不能忍,但是好歹算是都做出來了……

說起來,上一次全部做出來已經是什麼時候了啊,唉……

1. 題目一

給出題目一的試題連結如下:

1. 解題思路

這一題沒啥好多說的,就是分類討論一下,然後給出結果就行了。

唯一的問題就是注意一下一些邊界條件就行了。

2. 程式碼實現

給出python程式碼實現如下:

class Solution:
    def maximumTime(self, time: str) -> str:
        s = list(time)
        for idx, c in enumerate(s):
            if c != '?':
                continue
            if idx == 0:
                if time[idx+1] in "0123?":
                    s[
idx] = '2' else: s[idx] = "1" elif idx == 1: if s[idx-1] == "2": s[idx] = "3" else: s[idx] = "9" elif idx == 3: s[
idx] = "5" else: s[idx] = '9' return "".join(s)

提交程式碼評測得到:耗時20ms,佔用記憶體14.1MB。屬於當前最優演算法。

2. 題目二

給出題目二的試題連結如下:

1. 解題思路

這一題一開始想岔了,然後就錯了一次,後來想想事實上由於字元只會是英文字元,因此,我們只需要考慮以下幾種情況即可:

  1. s1中所有的字元都不大於某個字元ch,而s2中所有的字元都大於該字元;
  2. s2中所有的字元都不大於某個字元ch,而s1中所有的字元都大於該字元;
  3. s1與s2中所有的字元都變換為ch;

遍歷ch的26種可能性,然後分別比較結果取最小值即可。

2. 程式碼實現

給出python程式碼實現如下:

class Solution:
    def minCharacters(self, a: str, b: str) -> int:
        n1, n2 = len(a), len(b)
        cnt_a = Counter(a)
        cnt_b = Counter(b)
        res = math.inf
        for c in string.ascii_lowercase:
            if c == 'z':
                s1, s2 = math.inf, math.inf
            else:
                s1 = sum([cnt_a[ch] for ch in cnt_a if ch > c]) + sum([cnt_b[ch] for ch in cnt_b if ch <= c])
                s2 = sum([cnt_b[ch] for ch in cnt_b if ch > c]) + sum([cnt_a[ch] for ch in cnt_a if ch <= c])
            s3 = n1 + n2 - cnt_a[c] - cnt_b[c]
            res = min(res, s1, s2, s3)
        return res

提交程式碼評測得到:耗時108ms,佔用記憶體15.1MB。為當前最優演算法實現。

3. 題目三

給出題目三的試題連結如下:

1. 解題思路

這一題的思路事實上也挺直接的,就是求出每個座標對應的值的大小,然後排序之後求第k大的數即可。

因此,問題就在於如何快速地求出每個座標下的數。

由於x ^ x == 0,因此,我們可以得到遞推公式:

f[i][j] = matrix[i][j] ^ f[i-1][j] ^ f[i][j-1] ^ f[i-1][j-1]

2. 程式碼實現

給出python程式碼實現如下:

class Solution:
    def kthLargestValue(self, matrix: List[List[int]], k: int) -> int:
        n = len(matrix)
        m = len(matrix[0])
        nums = [matrix[0][0] for _ in range(n*m)]
        for i in range(n):
            for j in range(m):
                if i == 0 and j == 0:
                    continue
                elif i == 0:
                    matrix[i][j] = matrix[i][j] ^ matrix[i][j-1]
                elif j == 0:
                    matrix[i][j] = matrix[i-1][j] ^ matrix[i][j]
                else:
                    matrix[i][j] = matrix[i][j] ^ matrix[i-1][j] ^ matrix[i][j-1] ^ matrix[i-1][j-1]
                nums[i*m+j] = matrix[i][j]
        nums = sorted(nums, reverse=True)
        return nums[k-1]

提交程式碼評測得到:耗時3932ms,佔用記憶體42.2MB。

4. 題目四

給出題目四的試題連結如下:

1. 解題思路

這道題事實上就是一道數學題,我們可以寫一下頭部的幾個值的答案如下:

1, 
2, 3, 3
4, 5, 5, 6, 6, 6,
7, 8, 8, 9, 9, 9, 10, 10, 10, 10,
11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15
……

可以看到,基本而言,規律還是挺好找的。

因此,我們可以快速地給出對於每一行的長度如下: a i = i ⋅ ( i + 1 ) 2 a_i=\frac{i\cdot(i+1)}{2} ai=2i(i+1)

而需要填滿前 i i i行所需要的箱子數為:
S i = ∑ i ( a i ) = 1 6 n 3 + 1 2 n 2 + 1 3 n S_i = \sum_i(a_i) = \frac{1}{6}n^3 + \frac{1}{2}n^2 + \frac{1}{3}n Si=i(ai)=61n3+21n2+31n

因此,我們用二分法確定一下當給定n個箱子時,所需要消耗的最小的地面面積即可。

2. 程式碼實現

給出python程式碼實現如下:

class Solution:
    def minimumBoxes(self, n: int) -> int:
        def S(n):
            return (n*n*n + n*n*3 + n*2)/6
        
        def a(n):
            return n * (n+1) / 2
        
        if n == 1:
            return 1
        
        i, j = 1, n
        while i < j-1:
            m = (i+j) // 2
            if S(m) > n:
                j = m
            else:
                i = m
        base = i * (i+1) // 2

        delta = n - S(i)
        i, j = 0, delta
        while i < j-1:
            m = (i+j) // 2
            if a(m) >= delta:
                j = m
            else:
                i = m
        return int(base + j)

提交程式碼評測得到:耗時28ms,佔用記憶體14.4MB。為當前最優演算法實現。