• leetcode 695+547+200+130+257+51 岛屿的最大面积 DFS方法


    leetcode 695

    广度优先搜索一层一层遍历,每一层遍历到的所有新节点,要用队列先存储起来以备下一层遍历的时候再遍历;而深度优先搜索在遍历到一个新节点时立马对新节点进行遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到根节点 0 的情况是,继续对根节点 0 进行遍历,得到新节点 2,然后继续以上步骤。

    从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种  可达性 问题。

    在程序实现 DFS 时需要考虑以下问题:

    • 栈:用栈来保存当前节点信息,当遍历新节点返回时能够继续遍历当前节点。也可以使用递归栈。
    • 标记:和 BFS 一样同样需要对已经遍历过得节点进行标记。

    class Solution {
        public int maxAreaOfIsland(int[][] grid) {
            int m=grid.length;
            int n=grid[0].length;
            int maxv=0;
            for (int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(grid[i][j]==1){
                        maxv=Math.max(maxv,dfs(grid,i,j));
                    }
                }
            }
            return maxv;
        }
        public int dfs(int[][] grid,int i,int j){
            int m=grid.length;
            int n=grid[0].length;
            if(i<0||i>=m||j<0||j>=n) return 0;//注意这个是有可能的,因为比方是在0,0起点或者边界的时候都会出现越界,因为最后一行
            if(grid[i][j]==0) return 0;
            grid[i][j]=0;
            return dfs(grid,i-1,j)+dfs(grid,i,j-1)+dfs(grid,i+1,j)+dfs(grid,i,j+1)+1;//不要忘记+1,处理当前的数值
        }
    }

     leetcode 547

    这道题虽然说是用了深度遍历,但其实只是用了深度遍历的思想,也就是从行方向遍历,对每个人进行DFS,看与每个列方向的关系,遍历结束则返回结果。

    class Solution {
        public int findCircleNum(int[][] M) {     
            int[] vis=new int[M.length];  
            int count=0; 
            for(int i=0;i<M.length;i++){
                if(vis[i]==0) {
                    dfs1(M,i,vis);
                    count++;
                }
            }
            return count;
        }
        public void dfs1(int[][] M,int i,int[]vis){
            for(int j=0;j<M.length;j++){
                if(M[i][j]==1&&vis[j]==0){
                    vis[j]=1;
                    dfs1(M,j,vis);//一定要注意逻辑顺序
                    //如果出现stackflow那么说明一定是循环哪里的逻辑出现了问题导致死循环
                }
            }
        }
    }

     leetcode 200

    class Solution {
        int[][] dir={{1,0},{0,1},{0,-1},{-1,0}};
        public int numIslands(char[][] grid) {
            if(grid==null||grid.length==0) return 0;
            int m=grid.length;
            int n=grid[0].length;
            int count=0;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(grid[i][j]=='1'){
                        dfs(grid,i,j);
                        grid[i][j]='0';
                        count++;
                    }
                }
            }
            return count;
        }
        public void dfs(char[][]grid,int i,int j){
            int m=grid.length;
            int n=grid[0].length;
            if(i<0||j>=n||i>=m||j<0||grid[i][j]=='0'){return;}//如果越界则返回,注意范围设置
            grid[i][j]='0';
            for (int k=0;k<4;k++){
                dfs(grid,i+dir[k][0],j+dir[k][1]);
            }
    
        }
    }

      leetcode 130

    这道题的关键是读懂题,理解题的解题思路,因为要处理围着X的O,但是对于边缘的O以及与边缘O相互连通的O都不能进行处理,那么这个时候就有相应的不同条件下的不同处理方法

    class Solution {
        public void solve(char[][] board) {
            if(board==null||board.length==0) return;//边界条件要处理
            int m=board.length;
            int n=board[0].length;
            boolean flag;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    flag=(i==0||i==m-1||j==0||j==n-1);
                    //以边界O开始遍历
                    if(flag&&board[i][j]=='O'){
                        dfs(board,i,j);
                        // board[i][j]='#';
                    }
                    // if(board[i][j]=='O') board[i][j]='X'; //这里有可能里面的数据还没处理到,有可能到后面本应该是#
                }
            }
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(board[i][j]=='O') 
                    board[i][j]='X'; 
                    if(board[i][j]=='#')
                    board[i][j]='O'; 
    
                }
                }
        }
        public void dfs(char[][] board,int i,int j){
            int m=board.length;
            int n=board[0].length;
            if(i<0||i>=m||j<0||j>=n||board[i][j]=='X'||board[i][j]=='#') return;
            board[i][j]='#';//这里你可能把边上的O遍历出来的联通的所有的O都进行了换值,也就是都处理,主要是为了防止替换内部的O为X的时候弄错,所以给个标记,但是后面要再给还原回来。
            dfs(board,i-1,j);
            dfs(board,i,j-1);
            dfs(board,i+1,j);
            dfs(board,i,j+1);
        }
    }

    leetcode 257 

    二叉树的所有路径

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public List<String> binaryTreePaths(TreeNode root) {
            List<String> res=new ArrayList<>();
            if(root==null) return res;//注意判断边界情况
            dfs(res,"",root);
            return res;
        }
        public void dfs(List<String> res, String pes, TreeNode root){
            if(root==null) return;
            if(root.left==null&&root.right==null){
                res.add(pes+root.val);
                return;
            }
            pes+=root.val+"->";
            dfs(res,pes,root.left);//注意这里是字符值传递,不会影响下一语句
            dfs(res,pes,root.right);
        }
    }

     leetcode 51 N皇后 Hard

    总体而言这道题的思路如下:(这道题难度之所以是hard,是由于循环太容易把自己写糊涂了!!!)

    • 首先你要清楚每个皇后必须要分别占一行一列,也就是不能出现基本的在同一行或在同一列的皇后(这里还没有考虑斜线)
    • 斜线方面主要是考虑如何记录哪些斜线不能再放皇后,哪些可以继续放皇后
    • 第一个皇后从第一行第一列开始放起,放第二行皇后的位置,然后不断第一个皇后的列,直到把所有皇后都放好了(此时行号为N)再将最后一个皇后退栈,重新回溯遍历。
    import java.util.Arrays;
    import java.lang.Character;
    class Solution {
        int n;
        public char[][] que;
        public boolean uncol[];
        public boolean un45[];
        public boolean un135[];
        public List<List<String>> res;
        public List<List<String>> solveNQueens(int n) {
            res=new ArrayList<>();
            que=new char[n][n];
            // Arrays.fill(que,'.');
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    que[i][j] = '.';
                }
            }
            // Arrays.fill(que,'.');
            uncol=new boolean[n];
            un45=new boolean[2*n-1];//主要是用来存一共可能存的索引总数可能为2*n-1
            un135=new boolean[2*n-1];
            this.n=n;
            back(0);
            return res;
        }
        public void back(int row){
            if(row==n){
                List<String> list=new ArrayList<>();
                for(char[] ch:que){
                    list.add(new String(ch));
                }
                res.add(list);
                return;//结束最后一个点的back
            }
            for(int col=0;col<n;col++){
                int un451=row+col;
                int un1351=n-1-(row-col);
                if(uncol[col]||un45[un451]||un135[un1351]) continue;
                que[row][col]='Q';
                uncol[col]=un45[un451]=un135[un1351]=true;
                back(row+1);
                uncol[col]=un45[un451]=un135[un1351]=false;
                que[row][col]='.';
    
            }
    
        }
    }
  • 相关阅读:
    python js(JavaScript)初识
    python css盒子型 浮动
    12、液化
    11、高斯模糊—晶格化
    10、形状工具—渐变图标
    9、形状工具—雪糕
    8、形状工具—制作简单立体效果
    7、形状工具
    6、自由变换—再复制功能
    第三章-17、消息聊天界面
  • 原文地址:https://www.cnblogs.com/sjh-dora/p/12907440.html
Copyright © 2020-2023  润新知