• 代码随想录算法训练营第三十天| LeetCode332. 重新安排行程、LeetCode51. N 皇后、LeetCode37. 解数独


    一、LeetCode332. 重新安排行程

            1:题目描述(32. 重新安排行程

            给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

            所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

    • 例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。

            假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

            2:解题思路

            今天抄的代码,详细讲解请看:代码随想录-重新安排行程

    1. class Solution:
    2. def findItinerary(self, tickets: List[List[str]]) -> List[str]:
    3. # defaultdic(list) 是为了方便直接append
    4. tickets_dict = defaultdict(list)
    5. for item in tickets:
    6. tickets_dict[item[0]].append(item[1])
    7. # 给每一个机场的到达机场排序,小的在前面,在回溯里首先被pop(0)出去
    8. # 这样最先找的的path就是排序最小的答案,直接返回
    9. for airport in tickets_dict:
    10. tickets_dict[airport].sort()
    11. '''
    12. tickets_dict里面的内容是这样的
    13. {'JFK': ['ATL', 'SFO'], 'SFO': ['ATL'], 'ATL': ['JFK', 'SFO']})
    14. '''
    15. path = ["JFK"]
    16. def backtracking(start_point):
    17. # 终止条件
    18. if len(path) == len(tickets) + 1:
    19. return True
    20. for _ in tickets_dict[start_point]:
    21. #必须及时删除,避免出现死循环
    22. end_point = tickets_dict[start_point].pop(0)
    23. path.append(end_point)
    24. # 只要找到一个就可以返回了
    25. if backtracking(end_point):
    26. return True
    27. path.pop()
    28. tickets_dict[start_point].append(end_point)
    29. backtracking("JFK")
    30. return path

    二、LeetCode51. N 皇后

            1:题目描述(51. N 皇后

            按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

            n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

            给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

            每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

            2:解题思路

            代码也是抄的,哈哈哈,详细讲解请看:代码随想录-N皇后

    1. class Solution:
    2. def solveNQueens(self, n: int) -> List[List[str]]:
    3. if not n: return [] # n为空,返回[]
    4. board = [["."] * n for _ in range(n)] # 定义一个棋盘,n*n的二维数组
    5. res = []
    6. def isVaild(board, row, col):
    7. # 判断棋盘是否合法,row表示所在行,rol表示所在列
    8. # 判断同一列是否冲突
    9. for i in range(len(board)):
    10. if board[i][col] == "Q":
    11. return False
    12. # 判断左上角是否冲突
    13. i = row - 1
    14. j = col - 1
    15. while i>=0 and j>=0: # 一直向左上角进行判断
    16. if board[i][j] == "Q":
    17. return False
    18. i -= 1
    19. j -= 1
    20. # 判断右上角是否冲突
    21. i = row - 1
    22. j = col + 1
    23. while i>=0 and j <len(board): # 一直向右上角进行判断
    24. if board[i][j] == "Q":
    25. return False
    26. i -= 1
    27. j += 1
    28. # 左上角不冲突,右上角不冲突,所在列不冲突
    29. # 所在行只能放一个皇后,所以不存在冲突
    30. # 放皇后是从上到下依次放的,所以左下角和右下角还没有皇后,也不存在冲突
    31. return True
    32. # 放皇后
    33. def backtracking(board, row, n):
    34. # board表示当前放了皇后的棋盘
    35. # row表示当前需要放皇后的行
    36. # n表示皇后的个数
    37. if row == n:
    38. # 当行数等于了n,说明皇后已经放到了最后一行了
    39. temp_res = []
    40. for temp in board:
    41. temp_str = "".join(temp) # 将board中每一行的元素,转化成字符串
    42. temp_res.append(temp_str) # 将转化后的字符串,加入到一个列表中
    43. res.append(temp_res) # 再将列表加入到res中
    44. for col in range(n):
    45. # 遍历当前行的每个位置
    46. if not isVaild(board, row, col):
    47. # 判断当前位置的所在行、所在列、和对角线上是否已经有皇后了
    48. # 有皇后了,就直接进行下一个位置的遍历
    49. continue
    50. board[row][col] = "Q" # 在当前位置,放皇后
    51. # 放了皇后后,进入下一行的递归
    52. backtracking(board, row+1, n)
    53. # 回溯,把放皇后的位置,移除皇后,回到原始状态
    54. board[row][col] = "."
    55. backtracking(board, 0, n)
    56. return res

    三、LeetCode37. 解数独

            1:题目描述(37. 解数独

            编写一个程序,通过填充空格来解决数独问题。

            数独的解法需 遵循如下规则

    1. 数字 1-9 在每一行只能出现一次。
    2. 数字 1-9 在每一列只能出现一次。
    3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

            数独部分空格内已填入了数字,空白格用 '.' 表示。

            2:解题思路

            继续抄代码,详细讲解请看:代码随想录-解数独

    1. class Solution:
    2. def solveSudoku(self, board: List[List[str]]) -> None:
    3. """
    4. Do not return anything, modify board in-place instead.
    5. """
    6. self.backtracking(board)
    7. def backtracking(self, board):
    8. for i in range(len(board)): # 遍历行
    9. for j in range(len(board[0])): # 遍历列
    10. # 若空格内已有数字,则跳过
    11. if board[i][j] != ".": continue
    12. for k in range(1,10):
    13. # 往空格中尝试填写1-9
    14. if self.isVaild(i, j, k, board):
    15. # 如果填写的数字是合法的
    16. board[i][j] = str(k)
    17. result = self.backtracking(board) # backtracking函数有返回值
    18. if result: return True # 有满足条件的,就一层一层的向上返回True
    19. board[i][j] = "." # 不满足,就回溯,进行下一个数的尝试
    20. # 若数字1-9都不能成功填入空格,返回False无解
    21. return False
    22. return True # 有解
    23. def isVaild(self, row, col, val, board):
    24. # 一行中,数字不能重复
    25. for i in range(9):
    26. if board[row][i] == str(val):
    27. return False
    28. # 一列中,数字不能重复
    29. for j in range(9):
    30. if board[j][col] == str(val):
    31. return False
    32. # 3x3宫格内不能出现相同的数字
    33. start_row = (row // 3) * 3
    34. start_col = (col // 3) * 3
    35. for i in range(start_row, start_row+3):
    36. for j in range(start_col, start_col+3):
    37. if board[i][j] == str(val):
    38. return False
    39. return True
  • 相关阅读:
    解码方法数问题
    Vue源码总结
    Mysql和ES数据同步方案汇总
    黑马JVM总结(二十)
    Vue3.3指北(三)
    以太坊合并后的节点同步及共识层同步加速(geth+prysum)
    微服务分布式基于Springcloud的拍卖管理系统597wx
    rhcsa-文件内容显示
    链接脚本(1) --- 在默认的链接脚本中插入段
    uniapp实战项目 (仿知识星球App) - - 引入uView框架
  • 原文地址:https://blog.csdn.net/weixin_48323589/article/details/127797252