【二叉树的遍历以及有关题目】

二叉树理论基础

满二叉树:总共有k层,则节点总数为2^k - 1。根节点为第一层。
完全二叉树:除了最后一层,其余的都是满二叉树。并且最后一层从左到右连续。
二叉搜索树:搜索时间复杂度
平衡二叉搜索树:左右子树的高度差不能超过1。诸如C++里的map、set容器的实现原理就是平衡二叉树。
存储方式:
链式存储
线性存储:左孩子:2i+1;右孩子:2i+2
遍历方式:
1.深度优先搜索(二叉树的前、中、后序遍历)
利用递归的方式实现。也可利用迭代法实现。
2.广度优先搜索(层序遍历)
利用迭代法实现。依赖队列实现。

leetcode 144 二叉树的前序遍历

注意将结果数组定义到执行函数的外部作为类的成员属性,不然每次递归都要将前面的值清空。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> res = new ArrayList<Integer>();

    public List<Integer> preorderTraversal(TreeNode root) {
        //特判
        if(root == null){
            return res;
        }
        res.add(root.val);
        if(root.left != null){
            preorderTraversal(root.left);
        }
        if(root.right != null){
            preorderTraversal(root.right);
        }
        return res;
    }
}

leetcode 145 二叉树的后序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> res = new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        //特判
        if(root == null){
            return res;
        }
        if(root.left != null){
            postorderTraversal(root.left);
        }
        if(root.right != null){
            postorderTraversal(root.right);
        }
        res.add(root.val);
        return res;

    }

}

leetcode 94 二叉树的中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> res = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        //特判
        if(root == null){
            return res;
        }
        if(root.left != null){
            inorderTraversal(root.left);
        }
        res.add(root.val);
        if(root.right != null){
            inorderTraversal(root.right);
        }
        return res;

    }
}

leetcode 102 二叉树的层序遍历

注意先定义两个数组,一个用来记录当前节点的值,一个用来记录当前节点本身。再定义一个size,用来记录当前层的节点的个数,以便区分队列中有哪些节点是属于当前节点的。先考虑while循环条件不满足的情况

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        //建立一个队列:用LinkedList<>()实现
        Queue<TreeNode> queue = new LinkedList<>();
        //特判
        if(root == null){
            return res;
        }
        queue.offer(root);
        //定义一个size不断记录队列变化的长度
        int size = 1;
        while(!queue.isEmpty()){
            //记录当前层的节点的值
            List<Integer> cur = new ArrayList<>();
            //记录当前层的节点
            List<TreeNode> curNodes = new ArrayList<>();
            int j = size;//记录本层最初的size
            for(int i = 0; i < j; i++){
                TreeNode temp = queue.poll();
                curNodes.add(temp);
                --size;
                cur.add(temp.val);
            }
            res.add(cur);
            for(int i = 0; i < curNodes.size(); i++){
                root = curNodes.get(i);
                if(root.left != null){
                    queue.offer(root.left);
                    ++size;
                }
                if(root.right != null){
                    queue.offer(root.right);
                    ++size;
                }
            }
            
        }
        
        return res;
  
    }
}

层序遍历模板:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        //建立一个队列:用LinkedList<>()实现
        Queue<TreeNode> queue = new LinkedList<>();
        
        //特判
        if(root == null){
            return res;
        }
        queue.offer(root);
        while(!queue.isEmpty()){
            //记录当前层的节点的值
            List<Integer> cur = new ArrayList<>();
            //记录当前层节点的个数
            int size = queue.size();
            while(size != 0){
                TreeNode temp = queue.poll();
                cur.add(temp.val);
                if(temp.left != null){
                    queue.offer(temp.left);
                }
                if(temp.right != null){
                    queue.offer(temp.right);
                }
                size--;
            }
            res.add(cur);
        }
        
        return res;
  
    }
}

leetcode 226 翻转二叉树

采用前序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        //采用前序遍历
        if(root == null){return root;}
        TreeNode temp;
        temp = root.left;
        root.left = root.right;
        root.right = temp;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}

采用中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        //采用中序遍历
        if(root == null){return root;}
        invertTree(root.left);
        TreeNode temp;
        temp = root.left;
        root.left = root.right;
        root.right = temp;
        invertTree(root.left);
        return root;
    }
}

采用后序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        //采用后序遍历
        if(root == null){return root;}
        invertTree(root.left);
        invertTree(root.right);
        TreeNode temp;
        temp = root.left;
        root.left = root.right;
        root.right = temp;
        return root;
    }
}

leetcode 101 对称二叉树

首先确定遍历顺序,这一点非常重要。
本题采用后序遍历,因为只有当左右子树都处理完成之后,其得到的结果才可以作为判断对称的条件。
递归三部曲:
1.确定递归函数的参数以及返回值
2.确定递归的终止条件
3.处理单层递归的逻辑
注意:if else语句,代码越往下走,其就被越多的条件过滤过。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
     //1.确定递归函数的返回值类型和参数
    public boolean detectSymmetric(TreeNode left, TreeNode right){
            //2.确定递归函数的终止条件
            if(left != null && right == null){
                return false;
            }else if(left == null && right != null){
                return false;
            }else if(left == null && right == null){
                return true;
            }else if(left.val != right.val){
                return false;
            }else{
                //3.处理单层递归的逻辑
                boolean outside = detectSymmetric(left.left, right.right);
                boolean inside = detectSymmetric(left.right, right.left);
                return outside && inside;  
            }
    }
    public boolean isSymmetric(TreeNode root) {
        //采用后序遍历结合递归实现
        if(root == null){
            return true;
        }
        return detectSymmetric(root.left, root.right);

    }
}

leetcode 104 二叉树的最大深度

注意:求最大深度用前序遍历;求最大高度用后序遍历。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int getMax(int val1, int val2){
        return val1 > val2 ? val1 : val2; 
    }
    //采用后序遍历求最大高度,头节点的最大高度就是二叉树的最大深度
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftHeight = maxDepth(root.left);
        int rightHeight = maxDepth(root.right);
        return getMax(leftHeight, rightHeight) + 1;
        
    }
}

leetcode 111 二叉树的最小深度

注意退化成为单链表的二叉树的特殊情况。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int getMin(int val1, int val2){
        return val1 < val2 ? val1 : val2;
    }
    public int getMax(int val1, int val2){
        return val1 > val2 ? val1 : val2;
    }
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftHeight = minDepth(root.left);
        int rightHeight = minDepth(root.right);
        //处理退化成单链表这种特殊情况
        if(leftHeight == 0 || rightHeight == 0){
            return getMax(leftHeight, rightHeight) + 1;
        }
        else{
            return getMin(leftHeight, rightHeight) + 1;
        }


    }
}

leetcode 完全二叉树的节点个数

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        //采用后序遍历
        if(root == null){
            return 0;
        }else{
            int leftNodes = countNodes(root.left);
            int rightNodes = countNodes(root.right);
            return leftNodes + rightNodes + 1;  
        }
    }
}

leetcode 110 判断是否为平衡二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int max(int val1, int val2){
        return val1 > val2 ? val1 : val2;
    }
    public int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }else{
            int leftHeight = getHeight(root.left);
            int rightHeight = getHeight(root.right);
            return max(leftHeight, rightHeight) + 1;
        }
    }
    public boolean isBalanced(TreeNode root) {
        //采用后序遍历
        if(root == null){
            return true;
        }else{
            int res = getHeight(root.left) > getHeight(root.right) ? getHeight(root.left) - getHeight(root.right) : getHeight(root.right) - getHeight(root.left);
            if(res > 1){
                return false;
            }else{
                boolean leftIsBalanced = isBalanced(root.left);
                boolean rightIsBalanced = isBalanced(root.right);
                return leftIsBalanced && rightIsBalanced;
            }
        }
    }
}

注意:使用前序遍历求二叉树的深度需要用到回溯算法。比如当遍历到某一节点的左子树时,其局部变量depth会加1,当其左子树遍历完成时,若depth不减去1,那么遍历右子树的时候,其计算起始点便和左子树根节点不在同一位置,而是多加了1,所以要回溯减1。每一层递归只关心当前这一层的局部变量。

leetcode 257 二叉树的所有路径

只要有递归就一定有回溯。
注意:引用是地址拷贝
在写单层递归逻辑的时候需要考虑二叉树的遍历顺序。

leetcode 257 二叉树的所有路径

注意回溯的思想。
int类型转换为字符串类型的几种方法:
1.Integer.toString(int);
2.String.valueOf(int);
3.String var = num + “”;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> removeLast(List<String> path){
        List<String> temp = new ArrayList<>();
        for(int i = 0; i < path.size() - 2; i++){
            temp.add(path.get(i));
        }
        return temp;
    }
    public List<String> res(List<String> path){
        List<String> temp = new ArrayList<>();
        for(int i = 0; i < path.size() - 1; i++){
            temp.add(path.get(i));
        }
        return temp;
    }
    public List<String> res = new ArrayList<>();
    public List<String> path = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        //利用前序遍历
        if(path.size() != 0 && path.get(path.size() - 1) != "->" ){
            path.add("->");
        }
        path.add(Integer.toString(root.val));
        path.add("->");
        if(root.left == null && root.right == null){
            path = res(path);
            String str = "";
            for(int i = 0; i < path.size();i++){
                str += path.get(i);
            }
            res.add(str);
            return res;
        }
        if(root.left != null){
            binaryTreePaths(root.left);
            //回溯
            path = removeLast(path);
            
        }
        if(root.right != null){
            binaryTreePaths(root.right);
            //回溯
            path = removeLast(path);
            
        }
        return res;

    }
}

leetcode 404 左叶子之和

注意:左叶子是指是叶子节点且其是父亲的左孩子。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int result = 0;
    public int getLeftNodesSum(TreeNode root){
        if(root.left == null && root.right == null ){
            result += root.val;
            return result;
        }
        if(root.left != null){
            result = getLeftNodesSum(root.left);
        }
        
        if(root.right != null){
            //将右节点赋值为0
            root.right.val = 0;
            result = getLeftNodesSum(root.right);
        }
        return result;
    }
    public int sumOfLeftLeaves(TreeNode root) {
        //特判
        if(root == null || (root.left == null && root.right == null)){
            return 0;
        }
        return getLeftNodesSum(root);
    }
}

leetcode 513 找树左下角的值

本题同样利用回溯的思想。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //定义全局变量。就算递归遍历到最后一层的右节点,也不会修改res,因为其所在层数与最后一层的左节点相同
    public int maxDepth = 0;
    public int res;
    //定义递归函数,通过递归函数来修改全局变量的值
    public void getValue(TreeNode root, int depth){
        //定义递归终止的条件
        if(root.left == null && root.right == null){
            if(depth > maxDepth){
                maxDepth = depth;
                res = root.val;
            }
        }
        //定义单层递归的逻辑
        if(root.left != null){
            //回溯
            depth++;
            getValue(root.left, depth);
            depth--;
        }
        if(root.right != null){
            //回溯
            depth++;
            getValue(root.right, depth);
            depth--;
        }

    }

    public int findBottomLeftValue(TreeNode root) {
        getValue(root, 1);
        return res;
    }
}

leetcode 112 路径总和

本题依旧利用回溯的思想

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean res = false;
    public int target;
    public void findPath(TreeNode root,int sum){

        if(root.left == null && root.right == null){
            sum += root.val;
            if(sum == target){
                res = true;}
        }
        if(root.left != null){
            sum += root.val;
            findPath(root.left, sum);
            sum -= root.val;
        }
         if(root.right != null){
            sum += root.val;
            findPath(root.right, sum);
            sum -= root.val;
        }
    }
    public boolean hasPathSum(TreeNode root, int targetSum) {
        //特判
        if(root == null){
            return res;
        }
        target = targetSum;
        findPath(root,0);
        return res;
    }
}

leetcode 106 从中序与后序遍历序列构造二叉树

分为6步:
1.后序数组为0,表示为空节点
2.后序数组最后一个元素为节点元素
3.寻找中序数组位置作为切割点
4.切中序数组
5.切后序数组(用中序数组的左区间的大小来切后序数组,同样得到后序数组中左区间的节点,剩下的便是后序数组中右区间的大小)
6.递归处理左区间和右区间(root.left(左中序,左后序);root.right(右中序,右后序))
区间遵循左闭右开的原则。前序和后序不能还原一颗二叉树,因为左右区间的的界限无法确定。
注意:递归函数本身无返回值,则定义全局变量,利用递归函数改变全局变量的值。
递归函数有返回值,定义递归函数的局部变量,每进入一层递归都将局部变量初始化一次,所以要注意传递需要保留其累加值的局部变量。
注意:确定后序中右子树所对应的区间比较考察细节。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //定义递归函数的返回值和参数
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        //定义递归的终止条件
        if(postorder.length == 0){
            return null;
        }
        //定义该树的根节点
        TreeNode node = new TreeNode(postorder[postorder.length - 1]);
        //该树只有一个节点
        if(postorder.length == 1){
            return node; 
        }
        //定义单层递归逻辑
        int k = postorder[postorder.length - 1];
        int index = 0;//index表示中序的切割位置
        for(int i = 0; i < inorder.length; i++){
            if(inorder[i] == k){
                index = i;
                break;
            }
        }
        //切中序
        //定义左子树区间
        List<Integer> leftIn = new ArrayList<>();
        for(int i = 0; i <= index - 1; i++){
            leftIn.add(inorder[i]);
        }
        //定义右子树区间
        List<Integer> rightIn = new ArrayList<>();
        for(int i = index + 1; i < inorder.length; i++){
            rightIn.add(inorder[i]);
        }
        //计算后序里的左子树区间:后序的左子树区间一定与中序的左子树区间相同
        List<Integer> leftPos = new ArrayList<>();
        for(int i = 0; i < leftIn.size(); i++){
            leftPos.add(postorder[i]);
        }
        //计算后序里的右子树区间
        List<Integer> rightPos = new ArrayList<>();
        int temp = postorder.length - 1 - leftPos.size();
        int j = leftPos.size();
        while(temp != 0){
            rightPos.add(postorder[j]);
            j += 1;
            temp--;
        }
        
        
        //递归构造左子树
        //定义toArray工具方法
        
        int[] leftInArray = new int[leftIn.size()];
        for(int i = 0; i < leftIn.size(); i++){
            leftInArray[i] = leftIn.get(i);
        }
        int[] leftPosArray = new int[leftPos.size()];
        for(int i = 0; i < leftPos.size(); i++){
            leftPosArray[i] = leftPos.get(i);
        }
        node.left = buildTree(leftInArray, leftPosArray);
        //递归构造右子树
        int[] rightInArray = new int[rightIn.size()];
        for(int i = 0; i < rightIn.size(); i++){
            rightInArray[i] = rightIn.get(i);
        }
        int[] rightPosArray = new int[rightPos.size()];
        for(int i = 0; i < rightPos.size(); i++){
            rightPosArray[i] = rightPos.get(i);
        }
        node.right = buildTree(rightInArray, rightPosArray); 
        return node;

    }
}

leetcode 654 最大二叉树

本题递归的终止条件是nums数组只有一个元素。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        if(nums.length == 0){
            return null;
        }
        int max = nums[0];
        //记录最大元素的下标
        int flag = 0;
        for(int i = 1; i < nums.length; i++){
            if(nums[i] > max){
                max = nums[i];
                flag = i;
            }
        }
        TreeNode node = new TreeNode(max);
        //递归的终止条件
        if(nums.length == 1){
            TreeNode temp = new TreeNode(nums[0]);
            return temp;
        }
        //单层递归逻辑
        //左子树
        int[] left = new int[flag];
        for(int i = 0; i < flag; i++){
            left[i] = nums[i];
        }
        //右子树
        int[] right = new int[nums.length - 1 - left.length];
        int j = flag + 1;//右子树的起始节点的下标
        for(int i = 0; i < right.length; i++){
            right[i] = nums[j];
            j++;
        }
        node.left = constructMaximumBinaryTree(left);
        node.right = constructMaximumBinaryTree(right); 
        return node;

    }
}

leetcode 617 合并二叉树

本题用前序遍历。tree1与tree2同步进行遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //定义递归函数的返回值与参数
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        //定义递归终止条件
        if(root1 == null){
            return root2;
        }
        if(root2 == null){
            return root1;
        }
        //单层递归逻辑
        TreeNode node = new TreeNode(root1.val + root2.val);
        node.left = mergeTrees(root1.left, root2.left);
        node.right = mergeTrees(root1.right, root2.right);
        return node;
    }
}

leetcode 700 二叉搜索树中的搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null){
            return null;
        }
        //递归的终止条件
        if(root.left == null && root.right == null && root.val != val){
            return null;
        }
        //单层递归逻辑
        TreeNode res = root;//指向root的指针res
        if(val < root.val){
            res = searchBST(root.left, val);
        }
        if(val > root.val){
            res = searchBST(root.right, val);
        }
        if(val == root.val){
            return root;
        }
        return res;
    }
}

leetcode 98 验证二叉搜索树

二叉搜索树的中序遍历是升序排列的。
解法一:采用中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> res = new ArrayList<>();
    public void inorder(TreeNode root){
        if(root.left != null){
            inorder(root.left);
        }
        res.add(root.val);
        if(root.right != null){
            inorder(root.right);
        }
    }
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return false;
        }
        if(root.left == null && root.right == null){
            return true;
        }
        //中序遍历该树
        inorder(root);
        int[] nums = new int[res.size()];
        for(int i = 0; i < res.size();i++){
            nums[i] = this.res.get(i);
        }
        //判断nums数组是否是升序的
        int temp = nums.length - 1;
        int j = 0;
        while(temp != 0){
            if(nums[j] < nums[j+1]){
                --temp;
                ++j;
                continue;
            }
            break;
        }
        if(temp != 0){
            return false;
        }else{
            return true;
        }
    }
}

解法二:
利用双指针的思想。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //定义一个指向当前节点的前一个遍历节点的引用
    public TreeNode pre = null;
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        //采用中序遍历
        boolean left = isValidBST(root.left);
        if(pre != null && pre.val >= root.val){
            return false;
        }
        pre = root;
        boolean right = isValidBST(root.right);
        return left && right;
    }
}

leetcode 530 二叉搜索树的最小绝对差

注意:因为和BST相关,所以优先考虑中序遍历
本题利用双指针的方法,递归函数的返回值为void,传入的参数为当前节点cur。pre为当前节点的前一个中序遍历节点,初始为null。节点的移动用pre = cur实现。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int min = Integer.MAX_VALUE;
    public int min(int val1, int val2){
        return val1 < val2 ? val1 : val2;
    }
    public TreeNode pre = null;
    public void getMinimumDifferenceHelper(TreeNode cur){
        if(cur == null){
            return;
        }
        getMinimumDifferenceHelper(cur.left);
        if(pre != null){
            min = min(cur.val < pre.val ? pre.val - cur.val : cur.val - pre.val, min);
        }
        pre = cur;
        getMinimumDifferenceHelper(cur.right);
    }
    public int getMinimumDifference(TreeNode root) {
        getMinimumDifferenceHelper(root);
        return min;
    }
}

leetcode 501 二叉搜索树中的众数

解法一:(复杂版,不推荐)
需要用到双指针,优先队列,HashMap的遍历。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode pre = null;
    public int count = 1;
    public HashMap<Integer, Integer> map = new HashMap<>();
    public PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>()
        {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1; //大根堆
            }
        }
    );
    public List<Integer> res = new ArrayList<>();
    public void findModeHelper(TreeNode cur){
        if(cur == null){
            return;
        }
        //采用中序遍历
        findModeHelper(cur.left);
        if(pre != null){
            if(cur.val == pre.val){
               count++;
               map.put(pre.val, count);
            }
            if(cur.val != pre.val){
                map.put(cur.val, count);
                count = 1; 
            }
        }
        map.put(cur.val, count);
        pre = cur;
        findModeHelper(cur.right);
    }
    public int[] findMode(TreeNode root) {
        if(root.left == null && root.right == null){
            int[] res2 = new int[1];
            res2[0] = root.val;
            return res2;
        }
        findModeHelper(root);
        for(Integer value : map.values()){
            pq.add(value);
        }
        //value -> key
        int temp = pq.poll();
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
		if (Objects.equals(entry.getValue(), temp)) {
			res.add(entry.getKey());
		}
        }
        // int[] result = res.toArray(new int[res.size()]);
        int[] result = new int[res.size()];
        for(int i = 0; i < res.size(); i++){
            result[i] = res.get(i);
        }
        return result;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值