前言
继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬
292. Nim 游戏
# 数学
class Solution:
def canWinNim(self, n: int) -> bool:
return n % 4 != 0
# 动态规划
class Solution:
def canWinNim(self, n: int) -> bool:
if n <= 3: return True
dp = [0] * (n + 1)
dp[1] = 1
dp[2] = 1
dp[3] = 1
for i in range(4, n + 1):
dp[i] = not (dp[i - 1] or dp[i - 2] or dp[i - 3])
return dp[-1]
295. 数据流的中位数
# 二分插入
import bisect
class MedianFinder:
def __init__(self):
"""
initialize your data structure here.
"""
self.data = []
def addNum(self, num: int) -> None:
bisect.insort_left(self.data, num)
def findMedian(self) -> float:
n = len(self.data)
mid = (n - 1) // 2
if n % 2 == 1:
return self.data[mid]
else:
return (self.data[mid] + self.data[mid + 1]) / 2
# 笔者是手写二分的,第一次知道bisect这个库
297. 二叉树的序列化与反序列化
# 先序遍历
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
res = []
def preorder(root):
if not root:
res.append("#")
return
res.append(str(root.val))
preorder(root.left)
preorder(root.right)
preorder(root)
return ",".join(res)
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
d = iter(data.split(","))
def helper():
tmp = next(d)
if tmp == "#": return
node = TreeNode(int(tmp))
node.left = helper()
node.right = helper()
return node
return helper()
299. 猜数字游戏
class Solution:
def getHint(self, secret: str, guess: str) -> str:
from collections import Counter
s_c = Counter(secret)
g_c = Counter(guess)
res = [0, 0]
for x, y in zip(secret, guess):
if x == y:
s_c[x] -= 1
g_c[y] -= 1
res[0] += 1
for k in s_c & g_c:
res[1] += min(s_c[k], g_c[k])
return "{}A{}B".format(res[0], res[1])
# 优化
class Solution:
def getHint(self, secret: str, guess: str) -> str:
from collections import Counter
s_c = Counter(secret)
g_c = Counter(guess)
t = sum(i == j for i, j in zip(secret, guess)) #这一步有点妙
return "{}A{}B".format(t, sum((s_c & g_c).values()) - t)
300. 最长上升子序列
# 动态规划
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp or [0])
# 二分
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
import bisect
arr = []
for num in nums:
loc = bisect.bisect_left(arr, num)
arr[loc:loc + 1] = [num]
return len(arr)
# 二分这个方法太妙了,笔者只想到动规