60、单词搜索
给定一个 m x n
二维字符网格 board
和一个字符串单词 word
。如果 word
存在于网格中,返回 true
;否则,返回 false
。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true
示例 3:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false
提示:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board
和word
仅由大小写英文字母组成
思路解答:
-
深度优先搜索(DFS):使用深度优先搜索算法来在二维字符网格中搜索单词。
-
递归函数设计 :设计一个递归函数
dfs(i, j, k)
,其中i
和j
表示当前搜索的位置,k
表示当前匹配的单词字符索引。 -
边界条件:在递归函数中,首先检查当前位置是否越界,以及当前位置的字符是否与单词的字符匹配。
-
递归过程:在递归过程中,尝试向上、向下、向左、向右四个方向搜索,直到匹配完整个单词或搜索失败。
-
标记访问 :为了避免重复访问同一个位置,可以在访问过的位置标记为特殊字符(如
/
),并在递归结束后恢复原始字符。 -
遍历起点:遍历二维字符网格的所有位置作为搜索的起点,尝试从每个位置开始搜索单词。
-
返回结果 :如果在任何起点位置开始的搜索中找到匹配的单词,则返回
True
;否则,返回False
。def exist(board: list[list[str]], word: str) -> bool:
def dfs(i, j, k): if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return False if k == len(word) - 1: return True temp, board[i][j] = board[i][j], '/' res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1) board[i][j] = temp return res for i in range(len(board)): for j in range(len(board[0])): if dfs(i, j, 0): return True return False
61、分割回文串
给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串s。
示例 1:
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a"
输出:[["a"]]
提示:
1 <= s.length <= 16
s
仅由小写英文字母组成
思路解答:
-
判断回文串 :设计一个辅助函数
is_palindromic(s)
来判断一个字符串s
是否是回文串。 -
递归函数设计 :设计一个递归函数
backtrack(start, path)
,其中start
表示当前搜索的起始位置,path
记录当前的分割方案。 -
终止条件 :当
start
达到字符串s
的长度时,将当前分割方案加入结果集。 -
回溯过程 :在回溯过程中,从当前位置
start
开始,尝试将字符串分割成回文串,然后递归搜索剩余部分。 -
结果返回:返回所有生成的回文串分割方案。
def partition(s: str) -> list[list[str]]:
def is_palindromic(s): return s == s[::-1] def backtrack(start, path): if start == len(s): result.append(path[:]) return for end in range(start + 1, len(s) + 1): if is_palindromic(s[start:end]): path.append(s[start:end]) backtrack(end, path) path.pop() result = [] backtrack(0, []) return result
62、N皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n
个皇后放置在 n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n
,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:[["Q"]]
提示:
1 <= n <= 9
思路解答:
-
回溯算法框架 :
- 使用一个递归函数
backtrack(row)
,其中row
表示当前要放置皇后的行数。 - 在每一行中,遍历所有列,尝试将皇后放在每个位置。
- 对于每个位置,检查是否和之前的皇后位置冲突,如果不冲突则继续递归下一行。
- 使用一个递归函数
-
判断条件 :
- 使用三个集合
cols
、diagonals1
、diagonals2
来记录每一列、主对角线和副对角线上是否已经有皇后。 - 在放置皇后时,检查当前列、主对角线和副对角线是否已经有皇后,如果没有冲突则可以放置皇后。
- 使用三个集合
-
结束条件 :
- 当
row == n
时,表示所有皇后已经放置完毕,找到一个解决方案,将其加入结果集。 - 在递归中,每次成功放置皇后后,继续递归下一行。
- 当
-
回溯 :
- 在递归中,如果当前位置无法放置皇后,需要进行回溯,即将之前放置的皇后位置重置,并继续尝试下一个位置。
-
返回结果 :
- 将每个解决方案表示为一个棋盘,其中'Q'代表皇后,'.'代表空位。
def NQueens(n: int) -> list[list[str]]:
'''
判断在给定行 row 和列 col 上放置皇后是否与已放置的皇后相互攻击。
通过检查三个方向(列、主对角线和副对角线)是否存在皇后来实现,返回布尔值。
'''
def is_not_under_attack(row, col):
return not (cols[col] or diag1[row + col] or diag2[row - col])''' 在给定行 row 和列 col 上放置皇后,并相应地更新三组标志数组 cols(记录每列是否有皇后)、 diag1(记录主对角线上是否有皇后)和 diag2(记录副对角线上是否有皇后),将对应位置标记为1表示有皇后。 ''' def place_queen(row, col): queens[row] = col cols[col] = diag1[row + col] = diag2[row - col] = 1 ''' 移除在给定行 row 和列 col 上的皇后,并将三组标志数组相应位置恢复为0。 ''' def remove_queen(row, col): cols[col] = diag1[row + col] = diag2[row - col] = 0 ''' 当成功找到一种皇后放置方案时,将其转化为字符串形式并添加到解决方案列表 solutions 中。 每一行是一个字符串,由 '.' 和 'Q' 组成,表示棋盘的状态。 ''' def add_solution(): solution = [] for row, col in enumerate(queens): solution.append('.' * col + 'Q' + '.' * (n - col - 1)) solutions.append(solution) def backtrack(row): for col in range(n): if is_not_under_attack(row, col): place_queen(row, col) if row + 1 == n: add_solution() else: backtrack(row + 1) remove_queen(row, col) ''' 初始化三个标志数组:cols 用于记录各列是否有皇后,diag1 和 diag2 分别用于记录两条对角线上的皇后情况。 初始化皇后位置列表 queens 和存储解决方案的列表 solutions。 调用回溯函数 backtrack(0) 从第一行开始尝试放置皇后。 ''' cols = [0] * n diag1 = [0] * (2 * n - 1) diag2 = [0] * (2 * n - 1) queens = [0] * n solutions = [] backtrack(0) return solutions