DFS专题

154 阅读1分钟

1.875题 叶子相似的数

dfs去遍历到所有的叶子节点,加入到list里,然后判断是否相等即可

2.257题二叉树的所有路径

一样的添加! dfs

3.394题 字符串解码(出的比较多,再做一次)

dfs 这类括号匹配类的题目,用栈也用的很多!

DFS来做的:

class Solution {
    Queue<Character> queue;
    public String decodeString(String s) {
        queue = new LinkedList<>();
        char[] chars = s.toCharArray();
        for(char ch : chars){
            queue.add(ch);
        }
        return helper(chars,queue);

    }
    public String helper(char[] chars,Queue<Character> queue){
        StringBuilder sb = new StringBuilder();
        int num = 0;
        while(!queue.isEmpty()){
            char temp = queue.poll();
            if(Character.isDigit(temp)){
                num = num * 10 + temp - '0';
            }else if(temp == '['){
                String str = helper(chars,queue);
                for(int i = 0;i < num;i++){
                    sb.append(str);
                }
                num = 0;
            }else if(temp == ']'){

                break;
            }else{
                sb.append(temp);
            }
        }
        return sb.toString();
    }
}

非迭代版本

class Solution {
    public String decodeString(String s) {
        StringBuilder res = new StringBuilder();
        int multi = 0;
        LinkedList<Integer> stack_multi = new LinkedList<>();
        LinkedList<String> stack_res = new LinkedList<>();
        for(Character c : s.toCharArray()) {
            if(c == '[') {
                stack_multi.addLast(multi);
                stack_res.addLast(res.toString());
                multi = 0;
                res = new StringBuilder();
            }
            else if(c == ']') {
                StringBuilder tmp = new StringBuilder();
                int cur_multi = stack_multi.removeLast();
                for(int i = 0; i < cur_multi; i++) tmp.append(res);
                res = new StringBuilder(stack_res.removeLast() + tmp);
            }
            else if(c >= '0' && c <= '9') multi = multi * 10 + Integer.parseInt(c + "");
            else res.append(c);
        }
        return res.toString();
    }
}

4.113题 路径总和II

dfs比较经典的! 由于自己把res 和path设置成全局变量,所以每次返回结束之前,要path.remove掉!

5.494题 目标和

DFS

class Solution {

    int res = 0;
    int target;
int n;
    public int findTargetSumWays(int[] nums, int S) {

        n = nums.length;

        target = S;
        dfs(nums,0,0);
        return res;
    }

    public void dfs(int[] nums,int index ,int temp){

        if (index == n){
            if (temp == target){
                res ++;
            }
            return;
        }

        dfs(nums,index + 1 ,temp + nums[index]);
        dfs(nums,index + 1 ,temp - nums[index]);

    }
}

DP的方法

6.695题 岛屿的最大面积

就是因为这个题 自己挂的字节1!! 惨!!

直接沉岛操作就可以,每次访问的时候 变成0即可

7.130题 被围绕的区域

很好的题,从边界开始遍历,把遍历到的点设置为true,访问过,没有访问过的点全部变成'X'即可

class Solution {
    int n ,m;
    boolean[][] is_visited;
    public void solve(char[][] board) {
       if (board == null || board.length < 1 || board[0].length < 1){
            return;
        }
        n = board.length;
        m = board[0].length;
        is_visited = new boolean[n][m];
        for (int i = 0;i < n;i++){
            for (int j = 0;j < m;j++){
                is_visited[i][j] = false;
            }
        }

        for (int i = 0;i < n;i++) {
            if (board[i][m-1] == 'O') {
                dfs(board,i,m-1);
            }
            if (board[i][0] == 'O'){
                dfs(board,i,0);
            }
        }
        for (int i = 0;i < m;i++) {
            if (board[0][i] == 'O') {
                dfs(board,0,i);
            }
            if (board[n - 1][i] == 'O'){
                dfs(board,n-1,i);
            }
        }
        for (int i = 0 ;i < n;i++){
            for (int j = 0;j < m;j++){
                if (!is_visited[i][j]){
                    board[i][j] = 'X';
                }
            }
        }
    }

    public void dfs(char[][] board, int i,int j){
        if (i >= 0 && i < board.length && j >= 0 && j < board[0].length &&!is_visited[i][j] && board[i][j] == 'O'){
            is_visited[i][j] = true;
            dfs(board,i-1,j);
            dfs(board,i+1,j);
            dfs(board,i,j-1);
            dfs(board,i,j+1);
        }

    }
}

8.473题 棍子组成正方形

比较典型的dfs题目

先sort一下 然后依次去遍历,最后要剪枝一下,不然会超时~

dfs的题目如果数据量很大,剪枝也没用,有些题目剪枝可以优化很多!

9.109题 有序链表转换二叉搜索树

也是dfs! 找到中间的节点,然后一个head,一个tail去dfs ! 比较秒

10.二叉树的最大深度 最小深度

都是向上传递当前节点的深度

class Solution {
    public int minDepth(TreeNode root) {
        if (root == null){
            return 0;
        }

        return dfs(root);
    }

    public int dfs(TreeNode root){
        if (root == null){
            return 0;
        }
        int left = dfs(root.left);
        int right = dfs(root.right);
        return left == 0 || right == 0 ? left + right + 1 :1 + Math.min(left,right);

    }
}

11.leetcode200题 岛屿的数量

沉岛法!! 超级好用 看下并查集怎么去做的?

最好不用 改成 0 来做 可能出错!

12.leetcode827题 也太难了!!!

最后还是做出来了,可以再看看 再做一次

13.leetcode733题 图像渲染

也是那种类似的海岛题目

这是一个系列的问题!!