第七天
今天要学习的主题是,搜索与回溯算法。那先了解一下DFS和BFS吧。
DFS深度优先搜索
是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。在每个分岔路的时候做标记,当由一条路走到终点之后就回溯到上一个分岔路走另一条路,直到走完所有的路。 DFS搜索即是暴力搜索:把一条路走到底之后再回溯。
BFS广度优先搜索
它是一层一层地搜索,每一层搜索完了才会搜索下一层。 它的优势是能够找到最短的路径。
来做一题理解一吧,感觉第一题看起来就难难dei
十九题
剑指 Offer 12. 矩阵中的路径
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
思路: 本题的话感觉有点像走迷宫,那应该是使用深度优先搜索的方法来解。我的思路我一开始是默认他从左上角进来(但其实不是,这个后面说说)。想象自己就在这个“迷宫”里面走,可以上下左右走,通过判断下一步是否是自己需要的字符来决定要不要往那边走。
function exist(board: string[][], word: string): boolean {
const wordArr = word.split("")
const lineNum = board.length - 1
const colNum = board[0].length - 1
let i = 0
let j = 0
const z = [board[0][0]] //走到(0,0)的位置
board[0][0] = "" //将(0,0)设为空字符串
let result = null
const dfs = (i: number, j: number, z: string[], board: string[][]) => {
const Arr = [
{ item: board[i + 1 > lineNum ? i : i + 1][j], index: [i + 1, j] },
{ item: board[i][j + 1 > colNum ? j : j + 1], index: [i, j + 1] },
{ item: board[i - 1 < 0 ? i : i - 1][j], index: [i - 1, j] },
{ item: board[i][j - 1 < 0 ? j : j - 1], index: [i, j - 1] },
]
const filterArr = Arr.filter((item) => item.item === wordArr[z.length])
if (filterArr.length > 0) {
filterArr.forEach((item) => {
z.push(item.item)
board[item.index[0]][item.index[1]] = ""
i = item.index[0]
j = item.index[1]
dfs(i, j, z, board)
})
} else {
if (JSON.stringify(z) === JSON.stringify(wordArr)) {
return (result = true)
}
return (result = false)
}
}
dfs(i, j, z, board)
return result
};
这样确实可以得到从左上角进入的题目,但是!题目里没有提到说一定是从左上角进入,也就是说它其实是想让我们做到,在表中搜索任何一个可以进入的点,然后从那个点出发,找到任何可以满足的可能。于是我只能先在数组中去查找所有 输入的字符串的第一个字符 ,作为可以启动的点。
function exist(board: string[][], word: string): boolean {
const newBoard = board
const wordArr = word.split("")
const lineNum = board.length - 1
const colNum = board[0].length - 1
let i = 0
let j = 0
let z = []
let result = null
const firstLocation: [number, number][] = []
board.forEach((one, index) => {
one.forEach((two, index2) => {
if (two === wordArr[0]) {
firstLocation.push([index, index2])
}
})
})
const dfs = (i: number, j: number, z: string[], board: string[][]) => {
const Arr = [
{ item: board[i + 1 > lineNum ? i : i + 1][j], index: [i + 1, j] },
{ item: board[i][j + 1 > colNum ? j : j + 1], index: [i, j + 1] },
{ item: board[i - 1 < 0 ? i : i - 1][j], index: [i - 1, j] },
{ item: board[i][j - 1 < 0 ? j : j - 1], index: [i, j - 1] },
]
const filterArr = Arr.filter((item) => item.item === wordArr[z.length])
if (filterArr.length > 0) {
filterArr.forEach((item) => {
z.push(item.item)
board[item.index[0]][item.index[1]] = ""
i = item.index[0]
j = item.index[1]
dfs(i, j, z, board)
})
} else {
if (JSON.stringify(z) === JSON.stringify(wordArr)) {
return (result = true)
}
return (result = false)
}
}
const back: boolean[] = firstLocation.map((item) => {
i = 0
j = 0
z = []
result = null
const boards = newBoard
z.push(boards[item[0]][item[1]])
board[item[0]][item[1]] = ""
i = item[0]
j = item[1]
dfs(i, j, z, boards)
return result
})
return back.includes(true)
};
本来以为是很简单0.0结果写了两小时,不过就完全是靠自己的思路解题的了。
代码敲多了一定要起来走走喝水,要温故而知新。
下面是我的文章会引用到的作者和他的文章,都是跟着它学的,感谢。
作者:Krahets 链接:leetcode.cn/leetbook/re… 来源:力扣(LeetCode)