返回
剑指 Offer-Swift:回溯法突破矩阵迷宫
IOS
2024-02-07 10:57:13
引子:
踏入算法的江湖,剑指 Offer 是一场不能错过的试炼。第12关,矩阵中的路径,是一道看似简单实则暗藏玄机的回溯谜题。如同在错综复杂的矩阵中寻觅通途,唯有借助回溯法的慧眼,才能拨云见日,寻得出口。
一、回溯法的精髓:系统化探索,高效寻路
回溯法,是一把开启探索之门的钥匙,其奥义在于系统化地遍历问题每一步的所有可能选项,从中甄选出可行的解决方案。不同于蛮力法的一味穷举,回溯法在探索过程中不断回溯,剪枝无效选项,大幅提升寻路效率。
二、矩阵中的路径:曲径通幽,柳暗花明
本题要求我们判断一个矩阵中是否存在从起点到终点且不重复访问同一元素的路径。矩阵犹如一张暗藏玄机的迷宫,每个元素代表着前进道路上的岔路口。回溯法在这里大显身手,通过系统性地探索矩阵中每个岔路口,判断是否满足路径条件。
三、算法实现:回溯之舞,步步为营
func exist(_ board: [[Character]], _ word: String) -> Bool {
// 初始化回溯状态,设置是否找到路径的标记
var found = false
// 记录已访问过的单元格
var visited = [[Bool]](repeating: [Bool](repeating: false, count: board[0].count), count: board.count)
// 遍历矩阵中的每个单元格,作为回溯起点
for i in 0..<board.count {
for j in 0..<board[0].count {
// 以当前单元格为起点,进行回溯搜索
backtrack(i, j, board, word, &found, &visited)
// 如果找到路径,则立即返回
if found { return true }
}
}
return false
}
// 回溯搜索函数
private func backtrack(_ i: Int, _ j: Int, _ board: [[Character]], _ word: String, _ found: inout Bool, _ visited: inout [[Bool]]) {
// 判断是否越界或已访问过
if i < 0 || i >= board.count || j < 0 || j >= board[0].count || visited[i][j] {
return
}
// 判断当前单元格是否与单词首字母匹配
if word.first != board[i][j] {
return
}
// 标记单元格已访问
visited[i][j] = true
// 如果当前单元格是单词最后一个字母,则找到了路径
if word.count == 1 {
found = true
return
}
// 继续回溯搜索
backtrack(i-1, j, board, String(word.dropFirst()), &found, &visited) // 上
backtrack(i+1, j, board, String(word.dropFirst()), &found, &visited) // 下
backtrack(i, j-1, board, String(word.dropFirst()), &found, &visited) // 左
backtrack(i, j+1, board, String(word.dropFirst()), &found, &visited) // 右
// 回溯后标记单元格未访问
visited[i][j] = false
}
四、关键技术:回溯的精髓与应用
本算法的精髓在于回溯法的系统化探索。通过记录已访问单元格,剪枝无效选项,高效寻得满足路径条件的解决方案。回溯法不仅适用于本题,更是一种广泛应用于解决组合优化、搜索规划等复杂问题的通用技术。
五、总结:回溯之刃,斩断迷雾,直达彼岸
剑指 Offer 12.矩阵中的路径,看似简单,实则暗藏玄机。借助回溯法的慧眼,我们系统化地探索矩阵中的每条岔路,寻觅通往终点的路径。回溯之刃,斩断迷雾,直达彼岸,为我们揭示算法世界的无限可能。