【代码随想录训练营】【Day 32】【回溯-6】【待二刷】| Leetcode 332, 51, 37
需强化知识点
- 滑动窗口,固定结束位置版本
- 螺旋数组,建模为编程问题
题目
332. 重新安排行程
- sort reverse的用法,以及result.append(airport)的理解
from collections import defaultdict
class Solution:
def findItinerary(self, tickets):
targets = defaultdict(list) # 创建默认字典,用于存储机场映射关系
for ticket in tickets:
targets[ticket[0]].append(ticket[1]) # 将机票输入到字典中
for key in targets:
targets[key].sort(reverse=True) # 对到达机场列表进行字母逆序排序
result = []
self.backtracking("JFK", targets, result) # 调用回溯函数开始搜索路径
return result[::-1] # 返回逆序的行程路径
def backtracking(self, airport, targets, result):
while targets[airport]: # 当机场还有可到达的机场时
next_airport = targets[airport].pop() # 弹出下一个机场
self.backtracking(next_airport, targets, result) # 递归调用回溯函数进行深度优先搜索
result.append(airport) # 将当前机场添加到行程路径中
51. N 皇后
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
result = []
chessboard = ['.' * n for _ in range(n)]
self.backtracking(result, chessboard, n, 0)
return result
def backtracking(self, result, chessboard, n, row):
if row == n:
result.append(chessboard[:])
return
for col in range(n):
if self.isVaild(chessboard, row, col):
chessboard[row] = chessboard[row][:col] + 'Q' + chessboard[row][col+1:]
self.backtracking(result, chessboard, n, row+1)
chessboard[row] = chessboard[row][:col] + '.' + chessboard[row][col+1:]
def isVaild(self, chessboard, row, col):
for i in range(row):
if chessboard[i][col] == 'Q':
return False
i, j = row-1, col-1
while i >= 0 and j>= 0:
if chessboard[i][j] == 'Q':
return False
i -= 1
j -= 1
i, j = row-1, col+1
while i >=0 and j < len(chessboard):
if chessboard[i][j] == 'Q':
return False
i -= 1
j += 1
return True
37. 解数独
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
self.backtracking(board)
def backtracking(self, board: List[List[str]]) -> bool:
# 若有解,返回True;若无解,返回False
for i in range(len(board)): # 遍历行
for j in range(len(board[0])): # 遍历列
# 若空格内已有数字,跳过
if board[i][j] != '.': continue
for k in range(1, 10):
if self.is_valid(i, j, k, board):
board[i][j] = str(k)
if self.backtracking(board): return True
board[i][j] = '.'
# 若数字1-9都不能成功填入空格,返回False无解
return False
return True # 有解
def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
# 判断同一行是否冲突
for i in range(9):
if board[row][i] == str(val):
return False
# 判断同一列是否冲突
for j in range(9):
if board[j][col] == str(val):
return False
# 判断同一九宫格是否有冲突
start_row = (row // 3) * 3
start_col = (col // 3) * 3
for i in range(start_row, start_row + 3):
for j in range(start_col, start_col + 3):
if board[i][j] == str(val):
return False
return True