前言
继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬
331. 验证二叉树的前序序列化
# 二叉树的前序
class Solution:
def isValidSerialization(self, preorder: str) -> bool:
preorder = preorder.split(",")
i = 0
self.res = True
def helper():
nonlocal i
if i >= len(preorder):
self.res = False
return
tmp = preorder[i]
i += 1
if tmp == "#":
return
helper()
helper()
helper()
return i == len(preorder) and self.res
# 栈
class Solution:
def isValidSerialization(self, preorder: str) -> bool:
preorder = preorder.split(",")
stack = []
for item in preorder:
while stack and stack[-1] == "#" and item == "#":
stack.pop()
if not stack: return False
stack.pop()
stack.append(item)
return len(stack) == 1 and stack[0] == "#"
332. 重新安排行程
# hierholzer算法
class Solution:
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
from collections import defaultdict
graph = defaultdict(list)
res = []
for x, y in sorted(tickets)[::-1]:
graph[x].append(y)
def dfs(tmp):
while graph[tmp]:
dfs(graph[tmp].pop())
res.append(tmp)
dfs("JFK")
return res[::-1]
334. 递增的三元子序列
class Solution:
def increasingTriplet(self, nums: List[int]) -> bool:
first = float("inf")
second = float("inf")
for num in nums:
if num > second:
return True
if first > num:
first = num
elif first < num < second:
second = num
return False
335. 路径交叉
class Solution:
def isSelfCrossing(self, x) -> bool:
if len(x) < 4: return False
if len(x) == 4:return True if x[3] >= x[1] and x[2] <= x[0] else False
for i in range(3, len(x)):
if x[i] >= x[i-2] and x[i-1] <= x[i-3]:
return True
if i > 3 and x[i-1] == x[i-3] and x[i-4] + x[i] >= x[i-2]:
return True
if i > 4 and x[i-3]-x[i-5] <= x[i-1] <= x[i-3] and x[i-2]-x[i-4] <= x[i] <= x[i-2] and x[i-2] > x[i-4]:
return True
return False
336. 回文对
class Solution:
def palindromePairs(self, words: List[str]) -> List[List[int]]:
# 本身就是回文串单词
palidStr = []
# 翻转单词记录位置
rev_words = {}
# 结果
res = []
for idx, word in enumerate(words):
rev_words[word[::-1]] = idx
# 为了防止数组里有空字符串("")
if word == word[::-1]:
palidStr.append(idx)
for idx, word in enumerate(words):
if word:
# 这里没有 len(word) + 1
for i in range(len(word)):
left, right = word[:i], word[i:]
# 是否存在在单词左边加 使得成为回文串
if left == left[::-1] and right in rev_words and idx != rev_words[right]:
res.append([rev_words[right], idx])
# 同理
if right == right[::-1] and left in rev_words and idx != rev_words[left]:
res.append([idx, rev_words[left]])
else:
# 对于空字符串
for loc in palidStr:
if loc != idx:
res.append([idx, loc])
return res
337. 打家劫舍 III
class Solution:
def rob(self, root: TreeNode) -> int:
def helper(root):
if not root:
return 0, 0
left, prev1 = helper(root.left)
right, prev2 = helper(root.right)
return max(prev1 + prev2 + root.val, left + right), left + right
return helper(root)[0]
338. 比特位计数
class Solution:
def countBits(self, num: int) -> List[int]:
dp = [0] * (num + 1)
for i in range(1, num + 1):
dp[i] = dp[i // 2] + (i % 2)
return dp