【树】B014_二叉树中的列表(双重递归 | bfs + dfs)

一、题目描述

Given a binary tree root and a linked list with head as the first node. 

Return True if all the elements in the linked list starting from the head 
correspond to some downward path connected in the binary tree otherwise return False.

In this context downward path means a path that starts at some node and goes downwards.

二、题解

方法一:双重递归

  • 结束条件:
    • 如果 head 遍历到空,证明在树中可以找到一个路径,return true。
    • 如果 root 为空,证明找不到一条路径。
    • 如果 head.val == root.val,则可以从该结点出发继续搜索。
    • 如果 head.val != root.val,则链表不动,树继续向左右递归。

需要注意的点有二:

  • 在主方法的 if (head.val == root.val) { 中不能直接写以下语句,比如测试用例为时
    [1,10]
    [1,null,1,10,1,9]
    
    递归右子树时,因为 head.next.val != root.right.val 而直接 return false,导致结果为 false,与结果相反。
  • 在写递归结束条件时,应该将链表的判空写在数的判空的前面,因为树为空时,有可能是两边的任意一边空。并不能保证树全空。
return dfs(head.next, root.left) || dfs(head.next, root.right)

最后写下第一版代码:但只通过了 59/61 个样例,不知原因…

class Solution {
    boolean dfs(ListNode head, TreeNode root) {
        if (head == null)	return true;
        if (root == null) 	return false;
        if (head.val == root.val) {
            return dfs(head.next, root.left) || dfs(head.next, root.right);
        }
        return dfs(head, root.left) || dfs(head, root.right);
    }
    public boolean isSubPath(ListNode head, TreeNode root) {
        return dfs(head, root);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

方法二:bfs + dfs

用队列保存每一层的结点,当遇到匹配的结点,则从该结点 dfs。

为什么鬼,又栽在那个 59/61 上…

class Solution {
    boolean dfs(ListNode head, TreeNode root) {
        if (head == null)   return true;
        if (root == null)   return false;
        if (head.val == root.val)
            return dfs(head.next, root.left) || dfs(head.next, root.right);
        return dfs(head, root.left) || dfs(head, root.right);
    }
    public boolean isSubPath(ListNode head, TreeNode root) {
        Queue<TreeNode> q = new ArrayDeque<>();
        q.add(root);
        while (!q.isEmpty()) {
            TreeNode t = q.poll();
            if (t.val == head.val && dfs(head, t))
                return true;
            if (t.left != null)  q.add(t.left);
            if (t.right != null) q.add(t.right);
        }
        return false;
    }
}

我知道了,我直接拷贝的方法一的 dfs,而那个是不断匹配,而在方法二中。当 head.val != root.val 应该立刻返回 false 的,而不是继续匹配.

class Solution {
    boolean dfs(ListNode head, TreeNode root) {
        if (head == null)   return true;
        if (root == null)   return false;
        if (head.val != root.val)
            return false;
        return dfs(head.next, root.left) || dfs(head.next, root.right);
    }
    public boolean isSubPath(ListNode head, TreeNode root) {
        Queue<TreeNode> q = new ArrayDeque<>();
        q.add(root);
        while (!q.isEmpty()) {
            TreeNode t = q.poll();
            if (t.val == head.val && dfs(head, t))
                return true;
            if (t.left != null)  q.add(t.left);
            if (t.right != null) q.add(t.right);
        }
        return false;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

你可能感兴趣的:(#,树)