前言
繼續leetcode刷題生涯
這裏記錄的都是筆者覺得有點意思的做法
參考了好幾位大佬的題解,尤其是powcai大佬和labuladong大佬,感謝各位大佬
231. 2的冪
# 位計數
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
return n > 0 and bin(n).count("1") == 1
# 位操作
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
return n > 0 and n & (n - 1) == 0
232. 用棧實現隊列
# 兩個棧
class MyQueue:
def __init__(self):
"""
Initialize your data structure here.
"""
from collections import deque
self.stack = deque()
def push(self, x: int) -> None:
"""
Push element x to the back of queue.
"""
tmp = []
while self.stack:
tmp.append(self.stack.pop())
self.stack.append(x)
while tmp:
self.stack.append(tmp.pop())
def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if self.stack:
return self.stack.pop()
def peek(self) -> int:
"""
Get the front element.
"""
if self.stack:
return self.stack[-1]
def empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
return not bool(self.stack)
233. 數字 1 的個數
class Solution:
def countDigitOne(self, n: int) -> int:
if n<=0:
return 0
## 用數學的方法, 逐個計算,個位,十位,百位 等數位上的 "1" 的個數
count = 0
k = 1
while k <= n:
count += (n//(10*k))*k + min(max(n%(10*k)-k+1, 0), k) # 對個位也成立
k *= 10
return count
234. 迴文鏈表
# 翻轉後一半鏈表
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if not head or not head.next:return True
# 取中位數的上邊界,比如[1, 2, 2, 3] 取到是第二個2
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 奇數時候,中點位置下一個,(這樣翻轉才一樣)
if fast:
slow = slow.next
# 翻轉操作
prev = None
cur = slow
while cur:
tmp = cur.next
cur.next = prev
prev = cur
cur = tmp
# 對比
p1 = head
p2 = prev
while p1 and p2:
if p1.val != p2.val:
return False
p1 = p1.next
p2 = p2.next
return True
235. 二叉搜索樹的最近公共祖先
# 二叉搜索樹
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root and root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
elif root and root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root
236. 二叉樹的最近公共祖先
# 所有二叉樹
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root in {None, p, q}: return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
return left or right
237. 刪除鏈表中的節點
# 交換數值,刪除節點
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val, node.next.val = node.next.val, node.val
node.next = node.next.next
238. 除自身以外數組的乘積
# 左乘一遍,右乘一遍
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
res = [0] * n
res[0] = 1
for i in range(1, n):
res[i] = res[i - 1] * nums[i - 1]
right = 1
for i in range(n - 1, -1, -1):
res[i] *= right
right *= nums[i]
return res
239. 滑動窗口最大值
# 暴力 O(n^2) 超時
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
from collections import deque
n = len(nums)
if not nums or n < k : return []
windows = deque()
windows.extend(nums[:k])
res = []
res.append(max(windows))
for num in nums[k:]:
windows.popleft()
windows.append(num)
res.append(max(windows))
return res
# 單調數組 O(n)
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
from collections import deque
queue = deque()
res = []
for i in range(len(nums)):
# 把這個隊列索引號控制在k內
if queue and i - queue[0] + 1 > k:
queue.popleft()
# 維護一個單調遞減的數列
while queue and nums[queue[-1]] <= nums[i]:
queue.pop()
queue.append(i)
if i - k + 1 >= 0:
res.append(nums[queue[0]])
return res
# 動態規劃 O(n)
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if not nums: return []
n = len(nums)
left_max = [0] * n
left_max[0] = nums[0]
right_max = [0] * n
right_max[-1] = nums[-1]
res = []
for i in range(1, n):
left_max[i] = nums[i] if i % k == 0 else max(left_max[i - 1], nums[i])
for i in range(n - 2, -1, -1):
right_max[i] = nums[i] if i % k == 0 else max(right_max[i + 1], nums[i])
i = 0
while i + k - 1 < n:
res.append(max(right_max[i], left_max[i + k - 1]))
i += 1
return res
240. 搜索二維矩陣 II
# 從右上角開始
class Solution:
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if not matrix: return False
row = len(matrix)
col = len(matrix[0])
i = 0
j = col - 1
while i < row and j >= 0:
if matrix[i][j] == target:
return True
elif matrix[i][j] > target:
j -= 1
else:
i += 1
return False