代码随想录算法训练营day32 | 332.重新安排行程、51. N皇后、37. 解数独

332.重新安排行程

不会写,学习别人的代码,下面的代码没有用回溯的模板

class Solution:
    def __init__(self):
        self.adj = {}
        self.result = []

    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        # 根据航班目的站的字母顺序排序
        tickets.sort(key=lambda x: x[1])

        # 罗列每一站的下一个可选项
        for u, v in tickets:
            if u in self.adj:
                self.adj[u].append(v)
            else:
                self.adj[u] = [v]

        # 从JFK出发
        self.dfs("JFK")  # start with JFK
        return self.result[::-1]  # reverse to get the result

    def dfs(self, s):
        # if depart city has flight and the flight can go to another city
        while s in self.adj and len(self.adj[s]) > 0:
            # 找到s能到哪里,选能到的第一个机场
            v = self.adj[s][0]
            # 在之后的可选项机场中去掉这个机场
            self.adj[s].pop(0)
            # 从当前的新出发点开始
            self.dfs(v)

        self.result.append(s)

51. N皇后

回溯代码模板,比较好理解,树的深度为棋盘的行,树的宽度为棋盘的列

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        result = []
        chessboard = ["." * n for _ in range(n)]
        self.backtracking(n, 0, result, chessboard)
        return result

    def backtracking(self, n, row, result, chessboard):
        if n == row:
            result.append(chessboard[:])
            return
        for col in range(n):
            if not self.isValid(chessboard, row, col, n):
                continue
            chessboard[row] = chessboard[row][:col] + "Q" + chessboard[row][col+1:]
            print(chessboard)
            self.backtracking(n, row+1, result, chessboard)
            chessboard[row] = chessboard[row][:col] + "." + chessboard[row][col+1:]

    def isValid(self, chessboard, row, col, n):
        # 检查列
        for i in range(row):
            if chessboard[i][col] == "Q":
                return False
        # 检查135度角
        i = row - 1
        j = col - 1
        while i >= 0 and j >= 0:
            if chessboard[i][j] == "Q":
                return False
            i -= 1
            j -= 1
        # 检查45度角
        i = row - 1
        j = col + 1
        while i >= 0 and j < n:
            if chessboard[i][j] == "Q":
                return False
            i -= 1
            j += 1

        return True

37. 解数独

双重循环遍历数独的每一个空缺值,相当于树的深度。遍历数字1-9,相当于树的宽度。没有终止条件,但是在满足数独要求后会返回True,程序中止。

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):
        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 not self.is_valid(board, i, j, k):
                        continue
                    board[i][j] = str(k)
                    if self.backtracking(board):
                        return True
                    board[i][j] = "."
                return False
        return True

    def is_valid(self, board, row, col, value):
        # 检查一行上是否有重复数字
        for i in range(len(board[0])):
            if board[row][i] == str(value):
                return False
        # 检查一列上是否有重复数字
        for i in range(len(board)):
            if board[i][col] == str(value):
                return False
        # 检查九宫格内是否有重复数字
        for i in range(row//3 * 3, row//3 * 3 + 3):
            for j in range(col//3 * 3, col//3 * 3 + 3):
                if board[i][j] == str(value):
                    return False
        return True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值