dfs算法面试题总结

1.二叉树最大路径和

二叉树里面的路径被定义为:从该树的任意节点出发,经过父=>子或者子=>父的连接,达到任意节点的序列。

注意:

1.同一个节点在一条二叉树路径里中最多出现一次

2.一条路径至少包含一个节点,且不一定经过根节点

给定一个二叉树的根节点root,请你计算它的最大路径和

例如:
给出以下的二叉树,
 


最优路径是:2=>1=>3,或者3=>1=>2,最大路径和=2+1+3=6

数据范围:节点数满足 1≤1051≤n≤105 

要求:空间复杂度O(1),时间复杂度O(n)

输入:

{1,2,3}

复制返回值:

6

复制

解题思路:

dfs算法进行求解;通常最大值情况下有三种算法,第一种:动态规划,第二种是贪心算法 第三种:dfs 第四种暴力求解。面试过程中一般会说思路,再进行编码,如果思路不对,面试官会告诉你使用dfs。

dfs核心要点1.递归 2.终止条件

int max = Integer.MIN_VALUE;
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @return int整型
     */
    public int maxPathSum (TreeNode root) {
        // write code here
        //1.为空判断
        if (root == null) {
            return 0;
        }
        //2.递归
        dfs(root);
        return max;
    }

    public int dfs(TreeNode root) {
        //1.截至条件当节点为空也就退出
        if (root == null) {
            return 0;
        }
        //2.递归计算左边
        int left = dfs(root.left);
        //3.递归计算右边
        int right = dfs(root.right);
        //4.计算最大值 此时有几种情况 跟+左+右||根+左||根+右
        //4.1计算根+左int rootLeft = root.val+left;
        //4.2计算根+右 int rootRight = root.val + right;
        //因为返回得内容只有根左或者根右最大得情况,返回递归返回值
        int res = root.val+Math.max(0,Math.max(left,right));
        //计算根+左+右 使用函数处理负数情况
        int sum = root.val + Math.max(0,right) + Math.max(0,left);
        //计算最大值
        max = Math.max(max,Math.max(res,sum));
        return res;
    }

2.岛屿数量

给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。

岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。

例如:

输入

[

[1,1,0,0,0],

[0,1,0,1,1],

[0,0,0,1,1],

[0,0,0,0,0],

[0,0,1,1,1]

]

对应的输出为3

(注:存储的01数据其实是字符'0','1')

输入:

[[1,1,0,0,0],[0,1,0,1,1],[0,0,0,1,1],[0,0,0,0,0],[0,0,1,1,1]]

复制返回值:

3

复制

解题思路:

   将岛屿1的修改为0,当前节点的上下左右依次修改为0

public int solve (char[][] grid) {
        // write code here
        //健壮性判断
        if(grid==null) {
            return 0;
        }
        //定义返回值
        int res = 0;
        //双层for循环,遍历
        for(int up = 0;up<grid.length;up++) {
            for(int left=0;left<grid[0].length;left++) {
                //判断条件 为1情况下证明存在岛屿
                if(grid[up][left]=='1') {
                    res++;
                    //将周围的1设置为0
                    dfs(grid,left,up);
                }    
            }
        }
        return res;
    }

    public void dfs(char[][] arr,int left,int up) {
        //将该值修改为0
        arr[up][left]='0';
        //向右
        if(left+1<arr[0].length&&arr[up][left+1]=='1') {
            dfs(arr,left+1,up);
        }
        //向下
        if(up+1<arr.length&&arr[up+1][left]=='1') {
            dfs(arr,left,up+1);
        }
        //向左
        if(left-1>=0&&arr[up][left-1]=='1') {
            dfs(arr,left-1,up);
        }
        //向上
        if (up-1>=0&&arr[up-1][left]=='1') {
            dfs(arr,left,up-1);
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值