Leetcode周赛复盘——第 71 场力扣双周赛与第 279 场力扣周赛
雙周賽:
5984. 拆分數位后四位數字的最小和
class Solution:def minimumSum(self, num: int) -> int:a, b, c, d = sorted(list(map(int, str(num))))return 10 * (a + b) + c + dstr(num)得到字符串序列,然后用map函數對序列的每個字符轉換為數字,最后變為列表并且排序,最小的兩個數 a、b 一定在十位所以乘10,個位則是 c 和 d。
5985. 根據給定數字劃分數組
我的:
class Solution:def pivotArray(self, nums: List[int], pivot: int) -> List[int]:s = []e = []l = []for i in nums:if i < pivot:s.append(i)elif i == pivot:e.append(i)else:l.append(i)return s+e+l大佬的:
class Solution:def pivotArray(self, nums: List[int], pivot: int) -> List[int]:ans = []for x in nums:if x < pivot:ans.append(x)for x in nums:if x == pivot:ans.append(x)for x in nums:if x > pivot:ans.append(x)return ans區別不大,我是用三個列表分別記錄小于、等于和大于 pivot 的數,然后把它們加起來。當然也可以循環 nums 三次,依次添加三種數進入 ans 中。
5986. 設置時間的最少代價
class Solution:def minCostSetTime(self, startAt: int, moveCost: int, pushCost: int, targetSeconds: int) -> int:ans = 10**9 for tmp in range(10000): # 0000 到 9999 即所有情況a = list(map(int, str(tmp)))last = startAtneed = 0for x in a:if x != last:need += moveCostlast = xneed += pushCostif tmp // 100 * 60 + tmp % 100 == targetSeconds: # 正好是目標時間ans = min(ans, need)return ans這題的基本思路是分類討論,但是有點復雜。大佬的思路簡單粗暴,直接枚舉四個數字的所有情況,計算其代價,如果這四個數字對應的正好是目標時間,則比較其代價與當前最少代價,更新最少代價。
5987. 刪除元素后和的最小差值
class Solution:def minimumDifference(self, nums: List[int]) -> int:n = len(nums) // 3left = [0 for _ in range(3 * n + 1)] #左側最小的n個數的和right = [0 for _ in range(3 * n + 1)] #右側最大的n個數的和l_max = [] #每次要刪除那個最大的數for i in range(3 * n):left[i + 1] = left[i] + nums[i]heapq.heappush(l_max, -1 * nums[i]) # 最大堆if n <= i: # 堆中最多有 n 個元素,一旦超過就開始 popleft[i + 1] -= -1 * l_max[0] # 最大的數會被 pop,所以要減去heapq.heappop(l_max) # 刪除堆中最大的數r_min = [] #每次要刪除那個最小的數for i in range(3 * n - 1, -1, -1):right[i] = right[i + 1] + nums[i]heapq.heappush(r_min, nums[i]) # 最小堆if i < 2 * n: # 堆中最多有 n 個元素,一旦超過就開始 popright[i] -= r_min[0] # 最小的數會被 pop,所以要減去heapq.heappop(r_min) # 刪除堆中最小的數res = float('inf')for i in range(n, 2 * n + 1): # 枚舉分割點cur = left[i] - right[i] # 前面部分減后面部分的值res = min(res, cur)return res周賽
6000. 對奇偶下標分別排序
我的:
class Solution:def sortEvenOdd(self, nums: List[int]) -> List[int]:n = len(nums)odds = [nums[i] for i in range(n) if i % 2 == 1]evens = [nums[i] for i in range(n) if i % 2 == 0]odds.sort(reverse=True)evens.sort()ans = []for i in range(n):if i % 2 == 0:ans.append(evens[i // 2])else:ans.append(odds[(i-1) // 2])return ans大佬的:
class Solution:def sortEvenOdd(self, nums: List[int]) -> List[int]:a = sorted(nums[0::2])b = sorted(nums[1::2], reverse=True)to_ret = []while len(a)+len(b) > 0 :if len(a) > 0 :to_ret.append(a.pop(0))if len(b) > 0 :to_ret.append(b.pop(0))return to_ret優化點:1、取奇偶下標的元素不需要判斷下標的奇偶,只需要設置步長為 2 ,起點為 0、1即可;2、排序應習慣用 sorted ,可以少寫一行;3、要從頭開始取元素,可以用 pop(0)。
6001. 重排數字的最小值
我的:
class Solution:def smallestNumber(self, num: int) -> int:if num < 0:num_list = list(map(int, str(num)[1:]))num_list.sort(reverse=True)ans = 0for i in range(len(num_list)):ans = ans * 10 + num_list[i]ans = -anselif num == 0:ans = 0else:num_list = list(map(int, str(num)))num_list.sort()num_zeros = num_list.count(0)ans = 0if num_zeros == 0:for i in range(len(num_list)):ans = ans * 10 + num_list[i]else:ans = num_list[num_zeros]for i in range(num_zeros):ans = ans * 10for i in range(num_zeros+1, len(num_list)):ans = ans * 10 + num_list[i]return ans大佬的:
class Solution:def smallestNumber(self, num: int) -> int:if num == 0 :return numif num < 0 :return -int(''.join(sorted(str(num)[1:], reverse=True)))if num > 0 :num = str(num)ct = len([1 for t in num if t == '0'])num = sorted([t for t in num if not t == '0'])return int(num[0] + '0'*ct + ''.join(num[1:]))雖然都是分類討論找規律,但是在表達上我還是不夠簡潔。實際上就三種情況:num 等于 0,則返回 0;num 小于 0,則按照數字從大到小返回;num 大于 0,則取最小的正數作為第一個數,然后跟 0,最后是其余正數。
6002. 設計位集
class Bitset:def __init__(self, size: int):self.size = sizeself.listt = [0] * sizeself.vcount = 0 # 記錄 1 的個數self.isflip = False # 記錄是否翻轉def fix(self, idx: int) -> None:if not self.isflip :if not self.listt[idx] == 1 :self.vcount += 1self.listt[idx] = 1else :if not self.listt[idx] == 0 :self.vcount += 1self.listt[idx] = 0def unfix(self, idx: int) -> None:if not self.isflip :if not self.listt[idx] == 0 :self.vcount -= 1self.listt[idx] = 0else :if not self.listt[idx] == 1 :self.vcount -= 1self.listt[idx] = 1def flip(self) -> None:self.isflip = not self.isflipself.vcount = self.size - self.vcountdef all(self) -> bool:return self.vcount == self.sizedef one(self) -> bool:return self.vcount > 0def count(self) -> int:return self.vcountdef toString(self) -> str:if not self.isflip :return ''.join([str(t) for t in self.listt])else :return ''.join([str(1-t) for t in self.listt])這題很容易超時,必須優化,而優化的點主要是兩個:1、翻轉操作不需要真的翻轉,只需要用一個布爾標志記錄是否處于翻轉狀態即可;2、由于初始時全為 0,所以在賦值 1 時可以用一個變量記錄 1 出現的次數,這樣就不用每次都計算有多少個 1 了。
6003. 移除所有載有違禁貨物車廂所需的最少時間
正統的做法是動態規劃,參考這篇題解
class Solution:def minimumTime(self, s: str) -> int:n = len(s)suf = [0] * (n + 1)for i in range(n - 1, -1, -1):suf[i] = suf[i + 1] if s[i] == '0' else min(suf[i + 1] + 2, n - i)ans = suf[0]pre = 0for i, ch in enumerate(s):if ch == '1':pre = min(pre + 2, i + 1)ans = min(ans, pre + suf[i + 1])return ans另外有一種做法挺有意思,如圖所示:
總結
以上是生活随笔為你收集整理的Leetcode周赛复盘——第 71 场力扣双周赛与第 279 场力扣周赛的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 办冷食证的要求(冷食证备案)
- 下一篇: 在数组中找重复数、只出现一次的数或丢失数