算法总结 - 树 - 生成与变形

树的生成与变形

1. 树的生成

1.1 根据遍历建树

106. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]
Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

题目大意
给中序和后序遍历的两个数组,返回他们对应的二叉树。

解题思路
非递归: 用两个pointer从后向前遍历两个遍历数组,从右到左的建立树。
递归:已知后序遍历的最后一个值是根节点的值,找到中序遍历中根节点的位置,以此得到子树的边界:

  1. k 为根节点在中序遍历中的位置
  2. 左子树边界: 中序(instart, k - 1), 后序(poststart, poststart + (k - 1 - instart))
  3. 右子树边界: 中序(k + 1, inend), 后序(poststart + k - instart, postend - 1)

复杂度
非递归: TC: O(n) SC: O(n)
递归: TC: O(nlgn) SC: O(n)

//非递归解法
private int postIndex;
private int inIndex;
public TreeNode buildTree(int[] inorder, int[] postorder) {
   
    postIndex = postorder.length - 1;
    inIndex = inorder.length - 1;
    return traverse(postorder, inorder, null);
}

private TreeNode traverse(int[] postorder, int[] inorder, TreeNode root){
   
    if (postIndex < 0 || inIndex < 0 || (root != null && root.val == inorder[inIndex])) return null;
    TreeNode cur = new TreeNode(postorder[postIndex--]);
    cur.right = traverse(postorder, inorder, cur);
    inIndex--;
    cur.left = traverse(postorder, inorder, root);
    return cur;
}

//递归解法
public TreeNode buildTree(int[] inorder, int[] postorder) {
   
 int inStart = 0;
 int inEnd = inorder.length - 1;
 int postStart = 0;
 int postEnd = postorder.length - 1;

 return buildTree(inorder, inStart, inEnd, postorder, postStart, postEnd);
}

public TreeNode buildTree(int[] inorder, int inStart, int inEnd,
    int[] postorder, int postStart, int postEnd) {
   
    if (inStart > inEnd || postStart > postEnd)
        return null;
 
    int rootValue = postorder[postEnd];
    TreeNode root = new TreeNode(rootValue);
 
    int k = 0;
    for (int i = 0; i < inorder.length; i++) {
   
        if (inorder[i] == rootValue) {
   
            k = i;
            break;
        }
    }
 
    root.left = buildTree(inorder, inStart, k - 1, postorder, postStart,postStart + k - (inStart + 1));
    // Becuase k is not the length, it it need to -(inStart+1) to get the length
    root.right = buildTree(inorder, k + 1, inEnd, postorder, postStart + k- inStart, postEnd - 1);
    // postStart+k-inStart = postStart+k-(inStart+1) +1

 return root;
}

105. Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

题目大意
给中序和先序遍历的两个数组,返回他们对应的二叉树。

解题思路
非递归: 用两个pointer从前向后遍历两个遍历数组,从左到右的建立树。
递归:已知后序遍历的最后一个值是根节点的值,找到中序遍历中根节点的位置,以此得到子树的边界:

  1. k 为根节点在中序遍历中的位置
  2. 左子树边界: 中序(instart, k - 1), 先序(prestart + 1, poststart + (k - instart))
  3. 右子树边界: 中序(k + 1, inend), 先序(prestart + k - instart + 1, preend)

复杂度
非递归: TC: O(n) SC: O(n)
递归: TC: O(nlgn) SC: O(n)

//非递归解法
private int preIndex;
private int inIndex;

public TreeNode buildTree(int[] preorder, int[] inorder) {
   
    preIndex = 0;
    inIndex = 0;
    
    // peroder build inorder check
    return traverse(preorder, inorder, null);
}

private TreeNode traverse(int[] preorder, int[] inorder, TreeNode root){
   
    if ((root != null && root.val == inorder[inIndex]) || preIndex >= preorder.length) return null;
    TreeNode cur = new TreeNode(preorder[preIndex++]);
    cur.left = traverse(preorder, inorder, cur);
    inIndex++;
    cur.right = traverse(preorder, inorder, root);
    return cur;
}

//递归解法
public TreeNode b
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值