详细布置
今天这三道题都非常难,那么这么难的题,为啥一天做三道?
因为 一刷 也不求大家能把这么难的问题解决,所以 大家一刷的时候,就了解一下题目的要求,了解一下解题思路,不求能直接写出代码,先大概熟悉一下这些题,二刷的时候,随着对回溯算法的深入理解,再去解决如下三题。
大家今天的任务,其实是 对回溯算法章节做一个总结就行。
重点是看 回溯算法总结篇:
332.重新安排行程(可跳过)
Python使用used数组,lc1/81会超时:
class Solution:
def __init__(self):
self.result = []
self.path = ["JFK"]
def backtracking(self, tickets, cur, used):
if len(self.path)==len(tickets)+1:
self.result = self.path[:]
return True
for i, ticket in enumerate(tickets):
if ticket[0] == cur and used[i] == False:
used[i] = True
self.path.append(ticket[1])
state = self.backtracking(tickets, ticket[1], used)
if state: return True
used[i] = False
self.path.pop()
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
tickets.sort()
used = [False] * len(tickets)
self.backtracking(tickets, 'JFK', used)
return self.result
python版本只有优化到 使用字典 并逆序查找才可以通过所有的测试用例。
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) # 将当前机场添加到行程路径中
C++:
class Solution {
private:
unordered_map<string, map<string, int>> targets;
bool backtracking(int ticketNum, vector<string>& result) {
if (result.size()==ticketNum+1) return true;
for (pair<const string, int>& target: targets[result[result.size()-1]]) {
if (target.second > 0) {
result.push_back(target.first);
target.second--;
if (backtracking(ticketNum, result)) return true;
result.pop_back();
target.second++;
}
}
return false;
}
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> result;
result.push_back("JFK");
for (const vector<string>& vec: tickets) {
targets[vec[0]][vec[1]]++;
}
backtracking(tickets.size(), result);
return result;
}
};
51. N皇后(可跳过)
Python:
class Solution:
def __init__(self):
self.result = []
def isValid(self, row, col, chessboard):
# 检查列
for i in range(row):
if chessboard[i][col] == 'Q':
return False
# 检查45度
i, j = row-1, col-1
while i>=0 and j>=0:
if chessboard[i][j] == 'Q':
return False
i -= 1
j-= 1
# 检查135度
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
def backtracking(self, n, row, chessboard):
if row==n:
self.result.append(chessboard[:])
return
for col in range(n):
if self.isValid(row, col, chessboard):
chessboard[row] = chessboard[row][:col] + 'Q' + chessboard[row][col+1:]
self.backtracking(n, row+1, chessboard)
chessboard[row] = chessboard[row][:col] + '.' + chessboard[row][col+1:]
return
def solveNQueens(self, n: int) -> List[List[str]]:
if n==1: return [['Q']]
chessboard = ['.'*n for _ in range(n)]
self.backtracking(n, 0, chessboard)
return self.result
C++:
class Solution {
public:
vector<vector<string>> result;
void backtracking(int n, int row, vector<string>& chessboard) {
if (row==n) {
result.push_back(chessboard);
return;
}
for (int col=0; col<n; col++) {
if (isValid(row, col, chessboard)) {
chessboard[row][col] = 'Q';
backtracking(n, row+1, chessboard);
chessboard[row][col] = '.';
}
}
}
bool isValid(int row, int col, vector<string>& chessboard) {
// 检查列
for (int i=0; i<row; i++) {
if (chessboard[i][col]=='Q') return false;
}
// 检查45度
for (int i=row-1, j = col-1; i>=0 && j>=0; i--, j--) {
if (chessboard[i][j]=='Q') return false;
}
// 检查135度
for (int i=row-1, j=col+1; i>=0 && j<chessboard.size(); i--, j++) {
if (chessboard[i][j]=='Q') return false;
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
result.clear();
std:: vector<std::string> chessboard(n, std::string(n, '.'));
backtracking(n, 0, chessboard);
return result;
}
};
37. 解数独(可跳过)
Python:
class Solution:
def isValid(self, row, col, ele, board):
# 行
for i in range(9):
if board[row][i] == ele: return False
# 列
for j in range(9):
if board[j][col] == ele: 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] == ele: return False
return True
def backtracking(self, row, board):
for row in range(9):
for col in range(9):
if board[row][col] != ".": continue
for ele in range(1, 10):
if self.isValid(row, col, str(ele), board):
board[row][col] = str(ele)
if self.backtracking(row+1, board): return True
board[row][col] = '.'
return False
return True
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
self.backtracking(0, board)
C++:
class Solution {
public:
bool isValid(int row, int col, char ele, vector<vector<char>>& board) {
// 行
for (int i=0; i<9; i++) {
if (board[row][i]==ele) return false;
}
// 列
for (int j=0; j<9; j++) {
if (board[j][col]==ele) return false;
}
// 九宫格
int startRow = (row/3) * 3;
int startCol = (col/3) * 3;
for (int i=startRow; i<startRow+3; i++) {
for (int j=startCol; j<startCol+3; j++) {
if (board[i][j]==ele) return false;
}
}
return true;
}
bool backtracking(vector<vector<char>>& board) {
for (int row=0; row<9; row++) {
for (int col=0; col<9; col++) {
if (board[row][col]=='.') {
for (char ele='1'; ele<='9'; ele++) {
if (isValid(row, col, ele, board)) {
board[row][col] = ele;
if (backtracking(board)) return true;
board[row][col] = '.';
}
}
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};