继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,感谢各位大佬
class Solution:
def findSecondMinimumValue(self, root: TreeNode) -> int:
import collections
num = []
def helpper(root):
if root:
num.append(root.val)
helpper(root.left)
helpper(root.right)
helpper(root)
numdict = collections.Counter(num)
numdictorder = sorted(numdict)
if len(numdictorder)<2:
return -1
return numdictorder[1]
class Solution:
def flipLights(self, n: int, m: int) -> int:
if m == 0: return 1
if n == 1: return 2
if n == 2:
if m == 1: return 3
else: return 4
if m == 1: return 4
elif m == 2: return 7
else: return 8
class Solution:
def findNumberOfLIS(self, nums: List[int]) -> int:
n = len(nums)
if n == 0:return 0
dp = [1]*n
for i in range(1,n):
if nums[i] == nums[i-1]:
dp[i] = dp[i-1]
continue
else:
for j in range(i-1,-1,-1):
if nums[i] > nums[j] and dp[j]+1 > dp[i]:
dp[i] = dp[j]+1
mindp = min(dp)
maxdp = max(dp)
if maxdp == mindp:return n
dp2 = [1]*n
for i in range(1,n):
if dp[i] == mindp:
dp2[i]=1
continue
count=0
for j in range(i):
if dp[j] == dp[i]-1 and nums[j] < nums[i]:
count += dp2[j]
dp2[i] = count
res=0
for i in range(n):
if dp[i] == maxdp: res += dp2[i]
return res
class Solution:
def findLengthOfLCIS(self, nums: List[int]) -> int:
n = len(nums)
if n <= 1: return n
res = 0
cnt = 1
for i in range(1, n):
if nums[i] > nums[i-1]:
cnt += 1
else:
cnt = 1
res = max(res, cnt)
return res
# 笔者没做出来,题解里有个优化做的很好的如下
class Que: # 自己实现效率更高的队列操作
def __init__(self, len) -> int:
self.q = [0] * len
self.h, self.t = 0, 0 # 头、尾指针
def isNull(self) -> bool:
return self.h == self.t
def reset(self):
self.h, self.t = 0, 0
def push(self, val):
self.q[self.t] = val
self.t += 1
def pop(self):
if self.isNull():
return None
else:
ret = self.q[self.h]
self.h += 1
return ret
class Solution:
def cutOffTree(self, forest: List[List[int]]) -> int:
m, n = len(forest), len(forest[0])
self.go = [1, -1, n + 2, - n - 2]
woods = [
forest[i // (n + 2) - 1][i % (n + 2) - 1] if 0 < i // (n + 2) < m + 1 and 0 < i % (n + 2) < n + 1 else 0 for
i in range((m + 2) * (n + 2))] # 二维转一维操作
hl = []
for i, h in enumerate(woods):
if h > 0: hl.append((h, i))
hl = sorted(hl)
if len(hl) > 0 and hl[0] != n + 3:
hl.insert(0, (0, n + 3))
qu = Que(3000)
def astar(s, d1, d2, w, qu) -> int:
qu.reset()
sele = [False] * len(w)
res1, res2, step = 0, 0, 0
r1, r2 = False, False
if d1 == s: r1 = True
if d2 == s or d2 == 0: r2 = True
qu.push((s, 0))
sele[s] = True
while not qu.isNull() and not (r1 and r2): # 减枝
val = qu.pop()
for k in self.go:
idx = val[0] + k
if 0 != w[idx] and not sele[idx]: # 减枝
if not r1 and d1 == idx:
r1 = True
res1 = val[1] + 1
if not r2 and d2 == idx:
r2 = True
res2 = val[1] + 1
qu.push((idx, val[1] + 1))
sele[idx] = True
return res1 + res2 if r1 and r2 else -1
res = 0
for i in range(1, len(hl), 2): # 跳跃BFS
r = astar(hl[i][1], hl[i - 1][1], hl[i + 1][1] if i < len(hl) - 1 else 0, woods, qu)
if -1 == r: return -1
res += r
return res
class MagicDictionary:
def __init__(self):
self.d = {}
def buildDict(self, dict: List[str]) -> None:
for word in dict:
p = self.d
for c in word + '$':
if c not in p:
p[c] = {}
p = p[c]
def search(self, word: str) -> bool:
word += '$'
import collections
q = collections.deque([(self.d, False)])
for c in word:
for _ in range(len(q)):
node, modified = q.popleft()
if c in node:
q += [(node[c], modified)]
if not modified:
q += [(node[k], True) for k in node if k != c]
for node, modified in q:
if node == {} and modified:
return True
return False
class MapSum:
def __init__(self):
self.d = {}
def insert(self, key: str, val: int) -> None:
self.d[key] = val
def sum(self, prefix: str) -> int:
return sum(self.d[s] for s in self.d if s.startswith(prefix))
class Solution(object):
def checkValidString(self, strs):
n = len(strs)
num = 0
for i in range(n):
if strs[i] == ')':
num -= 1
else:
num += 1
if num < 0:
return False
num = 0
for i in range(n-1, -1, -1):
if strs[i] == '(':
num -= 1
else:
num += 1
if num < 0:
return False
return True
# 暴力递归
class Solution:
def judgePoint24(self, nums: List[int]) -> bool:
if not nums: return False
def helper(nums):
if len(nums) == 1: return abs(nums[0]-24) < 1e-6
for i in range(len(nums)):
for j in range(i + 1, len(nums)):
newnums = [nums[k] for k in range(len(nums)) if i != k != j]
if helper(newnums + [nums[i]+nums[j]]): return True
if helper(newnums + [nums[i]*nums[j]]): return True
if helper(newnums + [nums[i]-nums[j]]): return True
if helper(newnums + [nums[j]-nums[i]]): return True
if nums[j] != 0 and helper(newnums + [nums[i]/nums[j]]): return True
if nums[i] != 0 and helper(newnums + [nums[j]/nums[i]]): return True
return False
return helper(nums)
class Solution:
def validPalindrome(self, s: str) -> bool:
## 本身是回文字符串时,返回True
r = s[::-1]
if s == r: return True
## 本身不是回文字符串时,利用切片生成子字符串,判断其是否回文字符串
## 利用双指针,在生成子字符串时,既可以删除左指针指向的字符,也可以删除右指针指向的字符。
i, j =0, len(s)-1
while True: # 由于本身不是回文字符串,if语句必然执行产生return
if s[i] != s[j]:
## 由于这样切片s[i+1:j+1]在j=len(s)-1时会出错,改为s[i+1:j]+s[j]
return s[i:j] == r[i+1:j]+r[j] or s[i+1:j]+s[j] == r[i:j]
i += 1
j -= 1