周賽 第137場 2019 5 19

2021-09-23 01:43:04 字數 4509 閱讀 1995

目錄

1.最後一塊石頭的重量-easy。堆

2.刪除字串中的所有相鄰重複項-easy。棧

3.最長字串鏈-medium。dfs、dp

4.最後一塊石頭的重量 ii-medium。dp

有一堆石頭,每塊石頭的重量都是正整數。

每一回合,從中選出兩塊最重的石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x <= y。那麼粉碎的可能結果如下:

最後,最多隻會剩下一塊石頭。返回此石頭的重量。如果沒有石頭剩下,就返回 0。

1 <= stones.length <= 30

1 <= stones[i] <= 1000

用最大堆

# 最大堆

class solution(object):

def laststoneweight(self, stones):

h =

for s in stones:

while len(h):

if len(h) == 0:

return x

return 0

給出由小寫字母組成的字串 s,重複項刪除操作會選擇兩個相鄰且相同的字母,並刪除它們。

在 s 上反覆執行重複項刪除操作,直到無法繼續刪除。

在完成所有重複項刪除操作後返回最終的字串。答案保證唯一。

示例:輸入:"abbaca"

輸出:"ca" 解釋:例如,在 "abbaca" 中,我們可以刪除 "bb" 由於兩字母相鄰且相同,這是此時唯一可以執行刪除操作的重複項。之後我們得到字串 "aaca",其中又只有 "aa" 可以執行重複項刪除操作,所以最後的字串為 "ca"。

# 棧

class solution(object):

def removeduplicates(self, s):

st =

for c in s:

if not st or st[-1] != c:

else:

st.pop()

return "".join(st)

給出乙個單詞列表,其中每個單詞都由小寫英文本母組成。如果我們可以在 word1 的任何地方新增乙個字母使其變成 word2,那麼我們認為 word1 是 word2 的前身。例如,"abc" 是 "abac" 的前身。詞鏈是單詞 [word_1, word_2, ..., word_k] 組成的序列,k >= 1,其中 word_1 是 word_2 的前身,word_2 是 word_3 的前身,依此類推。從給定單詞列表 words 中選擇單詞組成詞鏈,返回詞鏈的最長可能長度。

示例:輸入:["a","b","ba","bca","bda","bdca"] 輸出:4 解釋:最長單詞鏈之一為 "a","ba","bda","bdca"。

3種做法

# dfs,先排序,遍歷所有詞鏈組合可能性

class solution(object):

def longeststrchain(self, words):

if not words:

return 0

words.sort(key = lambda w: len(w))

res = 1

n = len(words)

for i in range(n):

cur = self.helper(words, i, words[i], n, 1)

if cur > res:

res = cur

return res

def helper(self, words, index, w, n, level):

if index >= n-1:

return level

tmp_max = level

for i in range(index+1, n):

if len(words[i]) == len(w)+1 and self.isprebody(w, words[i]):

tmp_max = max(tmp_max, self.helper(words, i, words[i], n, level+1))

return tmp_max

def isprebody(self, w1, w2):

i = j = 0

flag = false

while i < len(w1) and j < len(w2):

if w1[i] == w2[j]:

i += 1

j += 1

else:

if not flag:

flag = true

j += 1

else:

return false

return true

# top_a = 0

# top_b = 0

# while top_a < len(a):

# if top_a + 1 < top_b:

# return false

# if a[top_a] == b[top_b]:

# top_b += 1

# top_a += 1

# else:

# top_b += 1

# return true

# dfs轉dp

class solution(object):

def longeststrchain(self, words):

dp = [1 for _ in range(len(words))]

res = 0

words.sort(key=len)

for i in range(len(words)):

for j in range(i):

if len(words[i]) == len(words[j]) + 1 and self.isprebody(words[j], words[i]):

dp[i] = max(dp[i], dp[j]+1)

res = max(res, dp[i])

return res

def isprebody(self, w1, w2):

i = j = 0

flag = false

while i < len(w1) and j < len(w2):

if w1[i] == w2[j]:

i += 1

j += 1

else:

if not flag:

flag = true

j += 1

else:

return false

return true

# top1 神仙做法

class solution(object):

def longeststrchain(self, words):

words.sort(key=len)

f = collections.defaultdict(int)

ans = 0

for w in words:

l = len(w)

for i in range(l):

f[w] = max(f[w], f[w[:i] + w[i+1:]] + 1)

# print(f)

ans = max(ans, f[w])

return ans

有一堆石頭,每塊石頭的重量都是正整數。

每一回合,從中選出任意兩塊石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x <= y。那麼粉碎的可能結果如下:

最後,最多隻會剩下一塊石頭。返回此石頭最小的可能重量。如果沒有石頭剩下,就返回 0。

示例:輸入:[2,7,4,1,8,1]

輸出:1 解釋: 組合 2 和 4,得到 2,所以陣列轉化為 [2,7,1,8,1], 組合 7 和 8,得到 1,所以陣列轉化為 [2,1,1,1], 組合 2 和 1,得到 1,所以陣列轉化為 [1,1,1], 組合 1 和 1,得到 0,所以陣列轉化為 [1],這就是最優值。

class solution 

};

# 2

class solution:

def laststoneweightii(self, stones) -> int:

s = sum(stones)

memo = {}

def dfs(i,c):

key = (i,c)

if key in memo:

return memo[key]

if i == 0:

return abs(s-c-c)

res = min(dfs(i-1,c),dfs(i-1,c+stones[i-1]))

memo[key] = res

return res

return dfs(len(stones),0)

Leetcode 第137場周賽解題報告

今天的比賽的題目相對來說比較 直白 不像前幾周都是一些特定的演算法,如果你沒學過不可能想出來。做了這些周,對leetcode比賽的題目也發現了一些 規律 一般前兩道題都很 簡單 只要有想法,直接敲 就能解出來。更多考察的是結果是否正確,速度其次。後兩道題有些難度,不同場次難度不一樣,也可能和不同人的...

第123場周賽

1,989.陣列形式的整數加法 方法一 逐位相加 思路 讓我們逐位將數字加在一起。舉乙個例子,如果要計算 123 與 912 的和。我們順次計算 3 2 2 1 1 9。任何時候,當加法的結果大於等於 10 我們要將進製的 1 加入下一位的計算中去,所以最終結果等於 1035。演算法 我們可以對以上...

第191場周賽

class solution return res 這裡有個注意的點,maxh maxw這兩個int的值的乘積會超過int的範圍,所以要先轉換為double class solution maxh maxh h horizontalcuts hcut 1 maxh h horizontalcuts ...