算法总结 - 树 - 传值

Tree

传值

这种题型算是树中比较难的类型,因为可能涉及到传递不同的值来决定最终的返回值。首先确定用什么结构,用什么方式传递值是需要仔细考虑的,另外在收集到信息后如何整合贡献到最终结果的过程也可能涉及到复杂的逻辑。所以,对于这个主题,我会尽量把每一个题目列出来分析。


333. Largest BST Subtree
Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it.
Note:
A subtree must include all of its descendants.

Example:

Input: [10,5,15,1,8,null,7]

   10 
   / \ 
  5  15 
 / \   \ 
1   8   7

Output: 3
Explanation: The Largest BST Subtree in this case is the highlighted one.
The return value is the subtree’s size, which is 3.
Follow up:
Can you figure out ways to solve it with O(n) time complexity?


题目大意
给一个二叉树,返回子树中最大的二叉搜索树。

解题思路

  1. 传值:
    a. 当前子树的最小值,最大值
    b. 子树包含最大二叉搜索树的大小

  2. 收集:
    从左右子树收集信息,如果左子树最大值小于当前节点,右子树的最小值大于当前节点,那么当前节点更新最大最小值,最大二叉搜索树为1 + 左子树最大搜索树大小 + 右子树最大搜索树大小。否则,只根据较大的那个搜索树更新信息。

复杂度
TC: O(n) SC: O(n)

class Result {
     // (size, rangeLower, rangeUpper) -- size of current tree, range of current tree [rangeLower, rangeUpper]
    int size;
    int lower;
    int upper;
    
    Result(int size, int lower, int upper) {
   
        this.size = size;
        this.lower = lower;
        this.upper = upper;
    }
}

int max = 0;

public int largestBSTSubtree(TreeNode root) {
   
    if (root == null) {
    return 0; }    
    traverse(root);
    return max;
}

private Result traverse(TreeNode root) {
   
    if (root == null) {
    return new Result(0, Integer.MAX_VALUE, Integer.MIN_VALUE); }
    Result left = traverse(root.left);
    Result right = traverse(root.right);
    if (left.size == -1 || right.size == -1 || root.val <= left.upper || root.val >= right.lower) {
   
        return new Result(-1, 0, 0);
    }
    int size = left.size + 1 + right.size;
    max = Math.max(size, max);
    return new Result(size, Math.min(left.lower, root.val), Math.max(right.upper, root.val));
}

298. Binary Tree Longest Consecutive Sequence
Given a binary tree, find the length of the longest consecutive sequence path.

The path refers to any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The longest consecutive path need to be from parent to child (cannot be the reverse).

Example 1:

Input:

   1
    \
     3
    / \
   2   4
        \
         5

Output: 3

Explanation: Longest consecutive sequence path is 3-4-5, so return 3.
Example 2:

Input:

   2
    \
     3
    / 
   2    
  / 
 1

Output: 2

Explanation: Longest consecutive sequence path is 2-3, not 3-2-1, so return 2.


题目大意
给一个二叉树,返回之中最长的连续路径的长度(只算由上往下的路径)。

解题思路
这题有两种解法,由顶向下(Top down)和由底向上(Bottom up),这里说下Top down的解法。

  1. 传值:
    a. 当前路径连续路径的长度
    b. 下一个应该碰到的目标节点

  2. 收集:
    如果当前节点等于目标节点,当前连续路径长度加一,更新全局最大连续路径长度。否则,当前连续路径长度为1。

复杂度
TC: O(n) SC: O(n)

//Top Down
int max = 0;
public int longestConsecutive(TreeNode root) {
   
    if(root == null) return 0;
    helper(root, root.val, 0);
    return max;
}

public void helper(TreeNode node, int target, int curLen){
   
    if(node == null) return;
    if(node.val == target){
   
        curLen += 1;
    }else{
   
        curLen = 1;
    }
    max = Math.max(curLen, max);
    helper(node.left, node.val + 1, curLen);
    helper(node.right, node.val + 1, curLen);
}

//Bottom up
private int maxLength = 0;
public int longestConsecutive(TreeNode root) {
   
    dfs(root);
    return maxLength;
}

private int dfs(TreeNode p) {
   
    if (p == null) return 0;
    int L = dfs(p.left) + 1;
    int R = dfs(p.right) + 1;
    if (p.left != null && p.val + 1 != p.left.val) {
   
        L = 1;
    }
    if (p.right != null && p.val + 1 != p.right.val) {
   
        R = 1;
    }
    int length = Math.max(L, R);
    maxLength = Math.max(maxLength, length);
    return length;
}

549. Binary Tree Longest Consecutive Sequence II
Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree.

Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and [4,3,2,1] are both considered valid, but the path [1,2,4,3] is not valid. On the other hand, the path can be in the child-Parent-child order, where not necessarily be parent-child order.

Example 1:

Input:
        1
       / \
      2   3

Output: 2
Explanation: The longest consecutive path is [1, 2] or [2, 1].

Example 2:

Input:

        2
       / \
      1   3

Output: 3
Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1].
Note: All the values of tree nodes are in the range of [-1e7, 1e7].


题目大意
给一个二叉树,返回之中最长的连续路径的长度。这次连续路径不必要一直由上往下。

解题思路

  1. 传值:
    a. 由此节点开始,单调递增的路径长度。
    b. 由此节点开始,单调递减的路径长度。

  2. 收集:
    如果当前节点的子节点与它的差值绝对值为1,那么检查子节点的连续路径长度,更新当前节点连续路径长度。

复杂度
TC: O(n) SC: O(n)

int maxval = 0;
public int longestConsecutive(TreeNode root) {
   
    longestPath(root);
    return maxval;
}
public int[] longestPath(TreeNode root) {
   
    if (root == null)
        return new int[] {
   0,0};
    int inr = 1, dcr = 1;
    if (root.left != null) {
   
        int[] l = longestPath(root.left);
        if (root.val == root.left.val + 1)
            dcr = l[1] + 1;
        else if (root.val == root.left.val - 1)
            inr = l[0] + 1;
    }
    if (root.right != null) {
   
        int[] r = longestPath(root.right);
        if (root.val == root.right.val + 1)
            dcr = Math.max(dcr, r[1] + 1);
        else if (root.val == root.right.val - 1)
            inr = Math.max(inr, r[0] + 1);
    }
    maxval = Math.max(maxval, dcr + inr - 1);
    return new int[] {
   inr, dcr};
}

863. All Nodes Distance K in Binary Tree
We are given a binary tree (with root node root), a target node, and an integer value K.

Return a list of the values of all nodes that have a distance K from the target node. The answer can be returned in any order.

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2

Output: [7,4,1]

Explanation:
The nodes that are a distance 2 from the target node (with value 5)
have values 7, 4, and 1.

Note that the inputs “root” and “target” are actually TreeNodes.
The descriptions of the inputs above are just serializations of these objects.

Note:

The given tree is non-empty.
Each node in the tree has unique values 0 <= node.val <= 500.
The target node is a node in the tree.
0 <= K <= 1000.


题目大意
给一个二叉树,一个目标节点,一个整数K。返回一个包含所有与目标节点距离为K的节点的列表。

解题思路

  1. 传值:
    a. 由当前节点往下,距离目标节点的距离。
  2. 收集:
    a. 当前节点就是目标节点,由此节点开始往下收集与它距离为K的节点。
    b. 当前节点的左节点与目标节点的距离left不为-1(即目标节点在左子树),如果左节点是目标节点,则从左节点开始往下收集与它距离为K的节点。递归的找与当前节点的右节点距离为K - 2 - left的节点(2代表当前节点与当前节点的左节点)。返回left + 1,表示当前节点与目标节点的距离。

复杂度
TC: O(n) SC: O(n)

List<Integer> ans;
TreeNode target;
int K;
public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {
   
    this.ans = new ArrayList<>();
    this.K = K;
    this
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值