[leetcode]第 14 天 搜索与回溯算法(中等)、第 15 天 搜索与回溯算法(中等)
12. 矩阵中的路径
思路
DFS+回溯
class Solution {
public boolean exist(char[][] board, String word) {
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(dfs(board, word, i, j, 0)) return true;
}
}
return false;
}
public boolean dfs(char[][] board, String word, int i, int j, int k){
if(i < 0 || i > board.length - 1 || j < 0 || j > board[0].length - 1 || board[i][j] != word.charAt(k)){
return false;
}
if(k == word.length() - 1) return true;
char c = board[i][j];// 临时保存
board[i][j] = 0;
boolean ret = dfs(board, word, i - 1, j, k + 1) || dfs(board, word, i, j - 1, k + 1) || dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i, j + 1, k + 1);
board[i][j] = c;
return ret;
}
}
13. 机器人的运动范围
思路
class Solution {
public int movingCount(int m, int n, int k) {
boolean[][] visited = new boolean[m][n];
return dfs(visited, m, n, k, 0, 0);
}
private int dfs(boolean[][] visited, int m, int n, int k, int i, int j){
if(i >= m || j >= n || bitSum(i) + bitSum(j) > k || visited[i][j]) return 0;
visited[i][j] = true;
// 当前 + 往下走 + 往右走
return 1 + dfs(visited, m, n, k, i + 1, j) + dfs(visited, m, n, k, i, j + 1);
}
private int bitSum(int x){
int sum = 0;
while(x != 0){
sum += x % 10;
x /= 10;
}
return sum;
}
}
34. 二叉树中和为某一值的路径
思路
class Solution {
LinkedList<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
recur(root, target);
return res;
}
void recur(TreeNode root, int tar){
if(root == null) return;
path.add(root.val);
tar -= root.val;
if(tar == 0 && root.left == null && root.right == null)
res.add(new LinkedList(path));
recur(root.left, tar);
recur(root.right, tar);
path.removeLast();
}
}
36. 二叉搜索树与双向链表
思路
dfs(cur): 递归法中序遍历;
终止条件: 当节点 cur 为空,代表越过叶节点,直接返回;
递归左子树,即 dfs(cur.left) ;
构建链表:
当 pre 为空时: 代表正在访问链表头节点,记为 head ;
当 pre 不为空时: 修改双向节点引用,即 pre.right = cur , cur.left = pre ;
保存 cur : 更新 pre = cur ,即节点 cur 是后继节点的 pre ;
递归右子树,即 dfs(cur.right) ;
treeToDoublyList(root):
特例处理: 若节点 root 为空,则直接返回;
初始化: 空节点 pre ;
转化为双向链表: 调用 dfs(root) ;
构建循环链表: 中序遍历完成后,head 指向头节点, pre 指向尾节点,因此修改 head 和 pre 的双向节点引用即可;
返回值: 返回链表的头节点 head 即可;
class Solution {
Node pre, head;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
dfs(root);
head.left = pre;
pre.right = head;
return head;
}
void dfs(Node cur) {
if(cur == null) return;
dfs(cur.left);
if(pre != null) pre.right = cur;
else head = cur;
cur.left = pre;
pre = cur;
dfs(cur.right);
}
}