Leetcode周賽 198學習筆記

2021-10-08 13:50:13 字數 4708 閱讀 9564

leetcode官方題解

1518

1、模擬:

先把所有的酒喝完,得到n個空酒瓶。隨後,每次可以拿e個空酒瓶換1瓶新酒,將這1瓶新酒喝完,與剩下的e-1個酒瓶,去換新酒……

res = numbottles

emptybottles = numbottles

while emptybottles >= exchangebottles:

# 換酒

emptybottles -= exchangebottles

# 喝完新酒

emptybottles +=

1# 多喝了一瓶

res +=

1return res

2、數學方法:

方法1中可以看出,每次換酒後,空瓶子會減少e-1個,直到剩餘空酒瓶無法換取新酒。假設當前一共換了n瓶,則有:emptybottles = emptybottles - n*(e-1)。因此,只需求解使得emptybottles - n*(e-1) < exchangebottles成立的最小n。

if numbottles < exchangebottles:

return numbottles

else

: numbottles +=

(numbottles-exchangebottles)

//(exchangebottles-1)

+1return numbottles

1519

演算法思想:dfs

tips:當題目只說給出一棵樹,或者說連通的無環無向圖時,需要考慮的含義,l = [a,b]不表示ab的父節點,只能說明二者存在連線。

dfs傳遞父節點方法:

edge_list = collections.defaultdict(

list

)# 儲存節點間關係

for i,j in edges:

edge_list[i]

edge_list[j]

defdfs

(cur_node,pre_node)

:# 統計當前節點的label

count_list[cur_node]

[ord

(labels[cur_node])-

ord(

'a')]=

1# 深度搜尋當前節點下所有相連節點的label

for next_node in edge_list[cur_node]

:# 排除父節點

if next_node != pre_node:

dfs(next_node,cur_node)

for i in

range(26

):count_list[cur_node]

[i]+= count_list[next_node]

[i]count_list =[[

0]*26

for _ in

range

(n)]

dfs(0,

-1)res =

for i in

range

(n):

[ord

(labels[i])-

ord(

'a')])

return res

dfs訪問列表標記

edge_list = collections.defaultdict(

list

)# 儲存節點間關係

for i,j in edges:

edge_list[i]

edge_list[j]

# 傳遞訪問標記列表

defdfs

(cur_node,visit)

: visit[cur_node]=1

count_list[cur_node]

[ord

(labels[cur_node])-

ord(

'a')]=

1for next_node in edge_list[cur_node]

:if visit[next_node]==0

:

dfs(next_node,visit)

for i in

range(26

):count_list[cur_node]

[i]+= count_list[next_node]

[i]count_list =[[

0]*26

for _ in

range

(n)]

visit =[0

for _ in

range

(n)]

dfs(

0,visit)

res =

for i in

range

(n):

[ord

(labels[i])-

ord(

'a')])

return res

1520

演算法思想:貪心

template:有乙個[0,n-1]的線段,其中n=s.length,要求我們用盡可能多的小線段覆蓋這個線段,且線段之間不能重合,線段之和最小。

answer_tips:將可用線段按右端點為第一關鍵字,長度為第二關鍵字進行排序。隨後從前往後遍歷線段,遇到可以加入的直接貪心新增。

要求2強調若乙個子字串包含c,則s中所有的c都應該包含於該字串。

# 先建立segment類

class

segment()

:def

__init__

(self,left=-1

,right=-1

):self.left = left

self.right = right

# 增加富比較

def__lt__

(self,other)

:if self.right == other.right:

return self.left > other.left

else

:return self.right < other.right

seg =

[segment(

)for _ in

range(26

)]# 預處理左右端點

lens =

len(s)

for i in

range

(lens)

: cur_ind =

ord(i)

-ord

('a'

)if seg[cur_ind]

.left ==-1

: seg[cur_ind]

.left = seg[cur_ind]

.right = i

else

: seg[cur_ind]

.right = i

# 處理每個片段,使之滿足條件2

for i in

range(26

):if seg[i]

.left !=-1

:# 處理當前片段的每個字元

j = seg[i]

.left

while j <= seg[i]

.right:

cur_ind =

ord(j)

-ord

('a'

)if seg[cur_ind]

.left >= seg[i]

.left and seg[cur_ind]

.right <= seg[i]

.right:

pass

else

: seg[i]

.left =

min(seg[i]

.left,seg[cur_ind]

.left)

seg[i]

.right =

max(seg[i]

.right,seg[cur_ind]

.right)

j = seg[i]

.left

j +=

1# 貪心演算法,此時需要先根據右端點進行排序,隨後按照字串長度排序,返回類中定義排序

seg.sort(

)res =

end =-1

for i in seg:

left, right = i.left, i.right

if left ==-1

:continue

# 此時已經完成排序,只需滿足條件1:無重疊(嚴格無重疊)

elif end ==-1

or left > end:

end = right1]

)return res

Leetcode周賽 202學習筆記

leetcode官方題解 1552 兩球之間的磁力 題意理解 給定position陣列,從中選取m個,使得這m個資料中,任意兩個數的差值的最小值最大。比如 position 1,2,3,6 m 3。那麼所有的選取情況為 1,2,3 1,2,6 2,3,6 1,3,6 每種情況下任意兩數差值的最小值為...

Leetcode 周賽記錄

希望能記錄到八月中旬開學吧。反正就沒啥意義 周賽回到了他溫柔可人的樣子 前兩周的分割我感覺可能寫起來會比較吃力 40 min搞定,很愉快 a字串分割沒啥好說的。b的話我覺得它應該降低記憶體空間或者增大長度,一看只有七個都brute force了。就不好玩了orz c葉子的定義有毛病 我很奇怪為什麼有...

leetCode第196場周賽學習

排序一下 然後列舉 只要不滿足等差數列性質就返回false,否則就返回true class solution return true 有一塊木板,長度為 n 個 單位 一些螞蟻在木板上移動,每只螞蟻都以 每秒乙個單位 的速度移動。其中,一部分螞蟻向 左 移動,其他螞蟻向 右 移動。當兩隻向 不同 方...