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]
不表示a
是b
的父節點,只能說明二者存在連線。
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 個 單位 一些螞蟻在木板上移動,每只螞蟻都以 每秒乙個單位 的速度移動。其中,一部分螞蟻向 左 移動,其他螞蟻向 右 移動。當兩隻向 不同 方...