算法D30 | 回溯算法6 | 332.重新安排行程 51. N皇后 37. 解数独

详细布置

今天这三道题都非常难,那么这么难的题,为啥一天做三道? 

因为 一刷 也不求大家能把这么难的问题解决,所以 大家一刷的时候,就了解一下题目的要求,了解一下解题思路,不求能直接写出代码,先大概熟悉一下这些题,二刷的时候,随着对回溯算法的深入理解,再去解决如下三题。 

大家今天的任务,其实是 对回溯算法章节做一个总结就行。 

重点是看 回溯算法总结篇:

代码随想录

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皇后(可跳过) 

代码随想录

视频讲解:这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后_哔哩哔哩_bilibili

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. 解数独(可跳过) 

代码随想录

视频讲解:回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独_哔哩哔哩_bilibili

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);
    }
};

总结

代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值