挑选自《图解算法与数据结构》中较为简单的部分题目。
原文地址如下:
https://leetcode.cn/leetbook/detail/illustration-of-algorithm/
dfs + 回溯
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
def dfs(i, j, k):
if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]:
return False
if k == len(word) - 1:
return True
board[i][j] = ''
res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
board[i][j] = word[k]
return res
for i in range(len(board)):
for j in range(len(board[0])):
if dfs(i, j, 0):
return True
return False
dfs + 回溯
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
vis = set()
def sum1(k):
b = 0
for a in str(k):
b += int(a)
return b
def dfs(i, j):
if i >= m or j >= n or k < sum1(i) + sum1(j) or (i, j) in vis:
return 0
vis.add((i, j))
return 1 + dfs(i + 1, j) + dfs(i, j + 1)
return dfs(0, 0)
真头疼啊,一点一点想想吧。
首先是寻找匹配节点,即T.val == B.val的时候。
A遍历为空,返回False。
B为空,返回为False。
匹配到B,返回True。
然后匹配B,左右匹配成功,B为空,返回True。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
def dfs(A, B):
if not A or not B:
return False
if B and A.val == B.val and check(A, B):
return True
return dfs(A.left, B) or dfs(A.right, B)
def check(root, tmplate):
if not root and tmplate:
return False
if not tmplate:
return True
if root.val != tmplate.val:
return False
return check(root.left, tmplate.left) and check(root.right, tmplate.right)
return dfs(A, B)
太巧妙了哇,想不到555
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return
tmp = root.left
root.left = self.invertTree(root.right)
root.right = self.invertTree(tmp)
return root
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
def recur(L, R):
if not L and not R:
return True
if not L or not R or L.val != R.val:
return False
return recur(L.left, R.right) and recur(L.right, R.left)
return not root or recur(root.left, root.right)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
if not root:
return []
res, queue = [], collections.deque()
queue.append(root)
while queue:
node = queue.popleft()
res.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
res, queue = [], collections.deque()
queue.append(root)
while queue:
tmp = []
for i in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(tmp)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
res, queue = [], collections.deque()
queue.append(root)
flag = False
while queue:
tmp = []
for i in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
if flag:
tmp.reverse()
flag = not flag
res.append(tmp)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
res, path = [], []
def recur(root, tar):
if not root: return
path.append(root.val)
tar -= root.val
if tar == 0 and not root.left and not root.right:
res.append(list(path))
recur(root.left, tar)
recur(root.right, tar)
path.pop()
recur(root, targetSum)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
path = []
def dfs(root, path):
if not root: return
path.append(root.val)
dfs(root.left, path)
dfs(root.right, path)
return path
dfs(root, path)
path.sort()
path.reverse()
return path[k-1]
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
res, queue = [], collections.deque()
queue.append(root)
while queue:
tmp = []
for i in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(tmp)
return len(res)
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root: return 0
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root: return True
return abs(self.deepth(root.left) - self.deepth(root.right)) <= 1 and \
self.isBalanced(root.left) and self.isBalanced(root.right)
def deepth(self, root):
if not root: return 0
return max(self.deepth(root.left), self.deepth(root.right)) + 1
class Solution:
def sumNums(self, n: int) -> int:
if n == 1:
return 1
n += self.sumNums(n-1)
return n
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val < p.val and root.val < q.val:
root = root.right
elif root.val > p.val and root.val > q.val:
root = root.left
else:
break
return root
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
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 not left and not right:
return
if not left:
return right
if not right:
return left
return root
哈希表(Set)。
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
dic = set()
for num in nums:
if num in dic:
return num
dic.add(num)
return -1
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
i, j = len(matrix) - 1, 0
while i >= 0 and j < len(matrix[0]):
if matrix[i][j] < target:
j += 1
elif matrix[i][j] > target:
i -= 1
else:
return True
return False
class Solution:
def firstUniqChar(self, s: str) -> str:
dict = {}
for c in s:
dict[c] = not c in dict
for c in dict:
if dict[c]:
return c
return ' '
class Solution:
def search(self, nums: List[int], target: int) -> int:
dict = collections.defaultdict(int)
for c in nums:
dict[c] += 1
return dict[target]
class Solution:
def missingNumber(self, nums: List[int]) -> int:
i, j = 0, len(nums) - 1
while i <= j:
m = (i + j) // 2
if nums[m] == m:
i = m + 1
else:
j = m - 1
return i
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
arr.sort()
return arr[:k]
class Solution:
def isStraight(self, nums: List[int]) -> bool:
joker = 0
nums.sort() # 数组排序
for i in range(4):
if nums[i] == 0: joker += 1 # 统计大小王数量
elif nums[i] == nums[i + 1]: return False # 若有重复,提前返回 false
return nums[4] - nums[joker] < 5 # 最大牌 - 最小牌 < 5 则可构成顺子
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
if head.val == val:
return head.next
pre, cur = head, head.next
while cur and cur.val != val:
pre, cur = cur, cur.next
if cur:
pre.next = cur.next
return head
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
i, j = 0, len(nums) - 1
while i < j:
while i < j and nums[i] & 1 == 1: i += 1
while i < j and nums[j] & 1 == 0: j -= 1
nums[i], nums[j] = nums[j], nums[i]
return nums
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
former, latter = head, head
for _ in range(k):
former = former.next
while former:
former, latter = former.next, latter.next
return latter
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
head = ListNode()
node = head
while list1 and list2:
if list1.val < list2.val:
node.next, list1 = list1, list1.next
else:
node.next, list2 = list2, list2.next
node = node.next
node.next = list1 if list1 else list2
return head.next
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
A, B = headA, headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
class Solution:
def reverseWords(self, s: str) -> str:
s = s.strip() # 删除首尾空格
strs = s.split() # 分割字符串
strs.reverse() # 翻转单词列表
return ' '.join(strs) # 拼接为字符串并返回
class Solution:
def fib(self, n: int) -> int:
a, b = 0, 1
for _ in range(n):
a, b = b, (a + b) % 1000000007
return a
class Solution:
def numWays(self, n: int) -> int:
a, b = 1, 1
for _ in range(n):
a, b = b, (a + b) % 1000000007
return a
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
for i in range(1, len(nums)):
nums[i] += max(nums[i-1], 0)
return max(nums)
class Solution:
def translateNum(self, num: int) -> int:
s = str(num)
a, b = 1, 1
for i in range(2, len(s) + 1):
a, b = (a + b if "10" <= s[i - 2:i] <= "25" else a), a
return a
class Solution:
def maxValue(self, grid: List[List[int]]) -> int:
row, column = len(grid), len(grid[0])
for i in range(row):
for j in range(column):
left = grid[i][j - 1] if j - 1 >= 0 else 0
upper = grid[i - 1][j] if i - 1 >= 0 else 0
grid[i][j] += max(left, upper)
return grid[row-1][column-1]
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
res = tmp = i = 0
for j in range(len(s)):
i = j - 1
while i >= 0 and s[i] != s[j]: i -= 1
tmp = tmp + 1 if tmp < j - i else j - i
res = max(res, tmp)
return res
class Solution:
def maxProfit(self, prices: List[int]) -> int:
profit, cost = 0, float("+inf")
for price in prices:
cost = min(price, cost)
profit = max(profit, price - cost)
return profit
class Solution:
def replaceSpace(self, s: str) -> str:
s = s.split(" ")
ss = ""
for i in range(len(s) - 1):
ss += s[i] + "%20"
ss += s[len(s) - 1]
return ss
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
stack = []
while head:
stack.append(head.val)
head = head.next
return stack[::-1]
class CQueue:
def __init__(self):
self.A, self.B = [], []
def appendTail(self, value: int) -> None:
self.A.append(value)
def deleteHead(self) -> int:
if self.B:
return self.B.pop()
if not self.A:
return -1
while self.A:
self.B.append(self.A.pop())
return self.B.pop()
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur, pre = head, None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:] + s[:n]
class Solution:
def myPow(self, x: float, n: int) -> float:
return x ** n
class Solution:
def printNumbers(self, n: int) -> List[int]:
res = []
for i in range(1, 10 ** n):
res.append(i)
return res
class Solution:
def hammingWeight(self, n: int) -> int:
x = list(bin(n))
res = 0
for i in x:
if i == '1':
res += 1
return res
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix:
return []
l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, []
while True:
for i in range(l, r + 1):
res.append(matrix[t][i])
t += 1
if t > b:
break
for i in range(t, b + 1):
res.append(matrix[i][r])
r -= 1
if l > r:
break
for i in range(r, l - 1, -1):
res.append(matrix[b][i])
b -= 1
if t > b:
break
for i in range(b, t - 1, -1):
res.append(matrix[i][l])
l += 1
if l > r:
break
return res
class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
stack, i = [], 0
for num in pushed:
stack.append(num)
while stack and stack[-1] == popped[i]:
stack.pop()
i += 1
return not stack