加载中...

[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);
    }
}
posted @ 2023-01-05 15:54  Vincy9501  阅读(11)  评论(0编辑  收藏  举报