三个月算法进阶--day88
目录
多数元素
class Solution:
def majorityElement(self, nums):
count = 0
candidate = None
for num in nums:
if count == 0:
candidate = num
count += (1 if num == candidate else -1)
return candidate
反转链表
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
cur = self.reverseList(head.next)
head.next.next = head
head.next = None
return cur
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
prev = None
ptr = head
while ptr:
temp = ptr.next
ptr.next = prev
prev = ptr
ptr = temp
return prev
数组中的第K个最大元素
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
import heapq
nums = [-num for num in nums]
heapq.heapify(nums)
for _ in range(k):
res = heapq.heappop(nums)
return -res
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
from queue import PriorityQueue as PQ
pq = PQ()
for i, t in enumerate(nums):
if i < k:
pq.put(t)
continue
pq.put(t)
pq.get()
return pq.get()
构建大顶堆
def heap_adjust(L, start, end):
temp = L[start]
i = start
j = 2 * i
while j <= end:
if j < end and L[j] < L[j + 1]:
j += 1
if temp < L[j]:
L[i] = L[j]
i = j
j = 2 * i
else:
break
L[i] = temp
L = collections.deque([50, 15, 7, 80, 2])
L.appendleft(0)
L_length = len(L) - 1
first_sort_count = L_length // 2
for i in range(first_sort_count):
heap_adjust(L, first_sort_count - i, L_length)
二叉搜索树中第K小的元素
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
def inorder(root: TreeNode) -> List[int]:
if root:
yield from inorder(root.left)
yield root.val
yield from inorder(root.right)
for n, val in enumerate(inorder(root)):
if n == k - 1:
return val
class Solution:
def KthSmallest(self, root: TreeNode, k: int) -> int:
stack = []
while True:
while root:
stack.append(root)
root = root.left
root = stack.pop()
k -= 1
if not k:
return root.val
root = root.right
2的幂
def isPowerOfTwo(self, n):
return n != 0 and n & (-n) == n
def isPowerOfTwo(self, n):
return n != 0 and not n & (n - 1)
二叉树的最近共同祖先
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root or root == p or root == q:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
if left:
return left
else:
return right
重建二叉树
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
self.preorder = preorder
self.tmp = {inorder[i]: i for i in range(len(inorder)) }
return self.recur(0, 0, len(inorder) - 1)
def recur(self, preroot, left, right):
if left > right:
return
index = self.tmp[self.preorder[preroot]]
root = TreeNode(self.preorder[preroot])
root.left = self.recur(preroot + 1, left, index - 1)
root.right = self.recur(preroot + index - left + 1, index + 1, right)
return root
字符串转换整数
INT_MAX = 2 ** 31 - 1
INT_MIN = -2 ** 31
class Automaton:
def __init__(self):
self.state = 'start'
self.sign = 1
self.ans = 0
self.table = {
'start': ['start', 'signed', 'in_number', 'end'],
'signed': ['end', 'end', 'in_number', 'end'],
'in_number': ['end', 'end', 'in_number', 'end'],
'end': ['end', 'end', 'end', 'end'],
}
def get_col(self, c):
if c.isspace():
return 0
if c == '+' or c == '-':
return 1
if c.isdigit():
return 2
return 3
def get(self, c):
self.state = self.table[self.state][self.get_col(c)]
if self.state == 'in_number':
self.ans = self.ans * 10 + int(c)
self.ans = min(self.ans, INT_MAX) if self.sign == 1 else min(self.ans, -INT_MIN)
elif self.state == 'signed':
self.sign = 1 if c == '+' else -1
class Solution:
def myAtoi(self, str: str) -> int:
automaton = Automaton()
for c in str:
automaton.get(c)
return automaton.sign * automaton.ans
青蛙跳台阶
class Solution:
def fib(self, n: int) -> int:
a, b = 1, 1
for _ in range(n):
a, b = b, a + b
return a
旋转数组的最小数字
class Solution:
def minArray(self, numbers: List[int]) -> int:
left, right = 0, len(numbers) - 1
while left < right:
pivot = left + (right - left) // 2
if numbers[pivot] < numbers[right]:
right = pivot
elif numbers[pivot] > numbers[right]:
left = pivot + 1
else:
right -= 1
return numbers[left]
矩阵中的路径
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
def dfs(m, n, k):
if m >= len(board) or m < 0 or n < 0 or n >= len(board[0]) or board[m][n] != word[k]:
return False
if k == len(word) -1:
return True
tmp, board[m][n] = board[m][n], "#"
res = dfs(m+1, n, k+1) or dfs(m, n+1, k+1) or dfs(m-1, n, k+1) or dfs(m, n-1, k+1)
board[m][n] = tmp
return res
for i in range(len(board)):
for t in range(len(board[0])):
if dfs(i, t, 0):
return True
return False