zoukankan      html  css  js  c++  java
  • 二叉树遍历的应用

    [LeetCode 98] Validate Binary Search Tree

    题目

    Given a binary tree, determine if it is a valid binary search tree (BST).
    
    Assume a BST is defined as follows:
    - The left subtree of a node contains only nodes with keys less than the node's key.
    - The right subtree of a node contains only nodes with keys greater than the node's key.
    - Both the left and right subtrees must also be binary search trees.
    

    测试案例

    Input:
        2
       / 
      1   3
    Output: true
    
        5
       / 
      1   4
         / 
        3   6
    Output: false
    Explanation: The input is: [5,1,4,null,null,3,6]. The root node's value
                 is 5 but its right child's value is 4.
    

    思路

    • 对二叉树进行中序遍历,记录下前继结点。若当前结点值小于前继结点时,二叉树就不是二叉搜索树

    代码如下

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        int pre;
        boolean isFirst = true;
        public boolean isValidBST(TreeNode root) {
            if(root == null){
                return true;
            }
            if(!isValidBST(root.left) || (!isFirst && pre >= root.val)){
                return false;
            }
            isFirst = false;
            pre = root.val;
            return isValidBST(root.right);
        }
    }
    

    [LeetCode 99] Recover Binary Search Tree

    题目

    Two elements of a binary search tree (BST) are swapped by mistake.
    Recover the tree without changing its structure.
    
    A solution using O(n) space is pretty straight forward.
    Could you devise a constant space solution?
    

    测试案例

    Input: [1,3,null,null,2]
    
       1
      /
     3
      
       2
    
    Output: [3,1,null,null,2]
    
       3
      /
     1
      
       2
    
    Input: [3,1,4,null,null,2]
    
      3
     / 
    1   4
       /
      2
    
    Output: [2,1,4,null,null,3]
    
      2
     / 
    1   4
       /
      3
    

    思路

    • 当二叉搜索树中交换两个结点后。对二叉树进行中序遍历时,交换后的第一个节点,大于其后继结点。第二个结点小于前继结点。
    • 利用这个性质,对二叉树进行中序遍历,并记录下前继结点。若当前结点值小于前继结点时,就将两个节点均保存到一个数组中
    • 若交换的两个节点为相邻结点。那么数组中保存的结点数为2;当交换的结点不相邻时,保存的结点是4个。但是,可以发现一个规律:被交换的两个节点总是位于数组的两端,即第0号元素和第 size - 1号元素。
    • 此外,当数组中已存满 4 个结点时,中序遍历可以结束。

    代码如下

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        TreeNode pre;
        //待插入位置
        int index = 0;  
        TreeNode[] arr = new TreeNode[4];
        boolean isFirst = true;
        public void recoverTree(TreeNode root) {
            find(root);
            if(index-- > 0){
                int temp = arr[0].val;
                arr[0].val = arr[index].val;
                arr[index].val = temp;
            }        
        }
        private void find(TreeNode root){
            if(root == null){
                return;
            }
            find(root.left);
            if(isFirst){
                isFirst = false;            
            }
            else if(pre.val > root.val){
                arr[index++] = pre;
                arr[index++] = root;
            }
            pre = root;
            if(index == 4){
                return;
            }
            find(root.right);
        }
    }
    

    [LeetCode 104] Maximum Depth of Binary Tree

    题目

    Given a binary tree, find its maximum depth.
    
    The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
    Note: A leaf is a node with no children.
    

    测试案例

    Input:
    Given binary tree [3,9,20,null,null,15,7],
      3
       / 
      9  20
        /  
       15   7
    return its depth = 3.
    

    代码如下

    class Solution {      
        public int maxDepth(TreeNode root) {
            if(root == null){            
                return 0;
            }
            int depth = maxDepth(root.left), temp = maxDepth(root.right);
            if(depth < temp){
                depth = temp;
            }
            return 1 + depth;
        }
    }
    

    [LeetCode 117] Populating Next Right Pointers in Each Node II

    二叉树前序遍历的变形(根、右子、左子)

    题目

    Given a binary tree
    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }
    Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.
    Initially, all next pointers are set to NULL.
    Note:
    
    You may only use constant extra space.
    Recursive approach is fine, implicit stack space does not count as extra space for this problem.
    

    测试案例

    input:
      1
       /  
      2    3
     /     
    4   5    7
    output:
    
         1 -> NULL
       /  
      2 -> 3 -> NULL
     /     
    4-> 5 -> 7 -> NULL
    

    思路

    对于每个结点 root,计算子结点的next值。

    当 right 不为空时,right 的 next 应为 root 的 next 的 左子(左子不为空时)或右子(左子为空,右子不为空),当next 左右子均为空时,要持续遍历 next,直至 next = null 或者找到某个非叶节点的 next。

    采用根,右、左结点的遍历顺序而不是先序遍历的原因是:遍历左子各结点时,需要当前层右边的结点的next都已算出。

    代码如下

    /**
     * Definition for binary tree with next pointer.
     * public class TreeLinkNode {
     *     int val;
     *     TreeLinkNode left, right, next;
     *     TreeLinkNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public void connect(TreeLinkNode root) {
            if(root == null || (root.left == null && root.right == null)){
                return;
            }
            TreeLinkNode cur = root.next;
            while(cur != null){
                if(cur.left != null){
                    cur = cur.left;
                    break;
                }
                else if(cur.right != null){
                    cur = cur.right;
                    break;
                }
                cur = cur.next;
            }
            if(root.right != null){
                root.right.next = cur;
                cur = root.right;
                connect(cur);
            }
            if(root.left != null){
                root.left.next = cur;
                connect(root.left);
            }
        }
    }
    

    此外,也仍然可以采用层序遍历的方法来计算。只是不够简洁。

  • 相关阅读:
    课程设计之第一次冲刺---第三天(11.13-11.14)
    课程设计之第一次冲刺---第二天(11.12)
    课程设计之第一阶段冲刺---第一天(11.11)
    团队贡献分分配
    尸体解剖
    回答自己的提问
    第三阶段冲刺--第2天
    第三阶段冲刺--第1天
    对其他组评价的反馈
    《一个程序猿的生命周期》读后感
  • 原文地址:https://www.cnblogs.com/echie/p/9604516.html
Copyright © 2011-2022 走看看