关于二叉树的算法总结

33 篇文章 1 订阅
29 篇文章 3 订阅

关于二叉树的算法总结

二叉树的种类

满二叉树

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

image-20220325092403098

这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节点的二叉树。

完全二叉树

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。

image-20220325092513201image-20220325092532979

二叉搜索树

二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

image-20220325092713352

[3,5,6,10,11,15,17]

平衡二叉搜索树

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

image-20220325092751219

image-20220325093057993image-20220325093401380

二叉树的存储方式

数组存储方式的分析

  • 优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。
  • 缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低

链式存储方式的分析

  • 优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。
  • 缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)

树存储方式的分析能

提高数据存储,读取的效率, 比如利用二叉排序树(Binary Sort Tree),既可以保证数据的检索速度,同时也可以保证数据的插入,删除,修改的速度。

二叉树的遍遍历方式

二叉树主要有两种遍历方式:

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
    1. 前序遍历(递归法,迭代法)
    2. 中序遍历(递归法,迭代法)
    3. 后序遍历(递归法,迭代法)
  2. 广度优先遍历:一层一层的去遍历。
    1. 层次遍历(迭代法)

深度优先遍历

  • 前序遍历:中左右
  • 中序遍历:左中右
  • 后序遍历:左右中

144. 二叉树的前序遍历 - 力扣(LeetCode) (leetcode-cn.com)

/**
 * 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> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        preorder(root,res);
        return res;
    }
    public void preorder(TreeNode cur,List<Integer> res){
        if(cur == null) return;//如果当前节点为空,则返回
        res.add(cur.val);
        preorder(cur.left,res);
        preorder(cur.right,res);
    }
}

94. 二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        inorder(root,res);
        return res;
    }
    public void inorder(TreeNode cur,List<Integer> res){
        if(cur == null) return;
        inorder(cur.left,res);
        res.add(cur.val);
        inorder(cur.right,res);
    }
}

145. 二叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        postorder(root,res);
        return res;
    }
    public void postorder(TreeNode cur,List<Integer> res){
        if(cur == null) return;
        postorder(cur.left,res);
        postorder(cur.right,res);
        res.add(cur.val);
    }
}

广度优先遍历

层序遍历

102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        BFS(root,res);

        return res;

    }

    //一层
    public void BFS(TreeNode root,List<List<Integer>> res){
        if(root == null) return;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            List<Integer> tempList = new ArrayList();
            int len = queue.size();
            while(len -- > 0){
                TreeNode temp = queue.poll();
                tempList.add(temp.val);
                if(temp.left != null) queue.offer(temp.left);
                if(temp.right != null) queue.offer(temp.right);
            }
            res.add(tempList);
        }
    
    }
}

Leecode

226. 翻转二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) return null;
        invertTree(root.left);//左
        invertTree(root.right);//右
        swap(root);
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if(root == null) return null;
        ArrayDeque<TreeNode> deq = new ArrayDeque<>();
        deq.offer(root);
        while(!deq.isEmpty()){
            int size = deq.size();
            while(size-->0){
                TreeNode temp = deq.poll();
                swap(temp);
                if(temp.left != null) deq.offer(temp.left);
                if(temp.right!= null) deq.offer(temp.right);
            }
        }
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
}

101. 对称二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public boolean isSymmetric(TreeNode root) {
        TreeNode left = root.left;
        TreeNode right = root.right;
        return compare(left,right);
    }
    public boolean compare(TreeNode left,TreeNode right){
        if(left == null &&right == null) return true; //都为空是对称的
        else if(left != null &&right == null) return false;//一个为空一个不为空,不是对称的
        else if(left == null && right != null) return false;
        else if(left != null && right != null && left.val != right.val) return false; //都不为空,值不等,不是对称的
        boolean out = compare(left.left,right.right); //左子树的左节点和右子树的右节点对比
        boolean in = compare(left.right,right.left);//右子树左节点和左子树的右节点对比
        return out & in;
    }
}
class Solution {
    public boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);
        while(!queue.isEmpty()){
            TreeNode nodeleft = queue.poll();
            TreeNode noderight = queue.poll();
            if(nodeleft == null && noderight == null) continue;
            if(nodeleft == null || noderight == null || nodeleft.val != noderight.val) return false;
            queue.offer(nodeleft.left);
            queue.offer(noderight.right);
            queue.offer(nodeleft.right);
            queue.offer(noderight.left);
        }
        return true;
    }
}

104. 二叉树的最大深度 - 力扣(LeetCode) (leetcode-cn.com)

后序遍历

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null) return 0;
        int letfdepth = maxDepth(root.left);//左子树的深度
        int righdepth = maxDepth(root.right);//右子树的深度
        return Math.max(letfdepth,righdepth)+1;
    }
}
class Solution {
    public int maxDepth(TreeNode root) {
        //层序遍历
        if(root == null) return 0;
        Queue<TreeNode> queue = new LinkedList();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()){
            depth ++;
            int size = queue.size();
            while(size-- > 0){
                TreeNode temp = queue.poll(); 
                if(temp.left != null) queue.offer(temp.left);
                if(temp.right != null) queue.offer(temp.right);
            }
        }
        return depth;
    }
}

111. 二叉树的最小深度 - 力扣(LeetCode) (leetcode-cn.com)

后序遍历

class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);
        if (root.left == null) {
            return rightDepth + 1;
        }
        if (root.right == null) {
            return leftDepth + 1;
        }
        // 左右结点都不为null
        return Math.min(leftDepth, rightDepth) + 1;   
    } 
}
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> que = new LinkedList();
        que.offer(root);
        int depth = 0;
        while(!que.isEmpty()){
            int size = que.size();
            depth ++;
            while(size-- > 0){
                TreeNode temp = que.poll();
                if(temp.left == null && temp.right == null) return depth;
                if(temp.left != null) que.offer(temp.left);
                if(temp.right != null) que.offer(temp.right);
            }
        }
        return depth;
    }
}

222. 完全二叉树的节点个数 - 力扣(LeetCode) (leetcode-cn.com)

仅适合完全二叉树的算法

满二叉树的结点数为:2^depth - 1
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        int leftDepth = getDepth(root.left);
        int rightDepth = getDepth(root.right);
        // 左子树是满二叉树
        // 2^leftDepth其实是 (2^leftDepth - 1) + 1 ,左子树 + 根结点
        if(leftDepth == rightDepth) return (1<<leftDepth) + countNodes(root.right);
        //右子树是满二叉树
        else return (1<<rightDepth) + countNodes(root.left);
    }
    public int getDepth(TreeNode node){
        int depth =0;
        while(node != null){
            node = node.left;
            depth ++;
        }
        return depth;
    }
}

适合所有的二叉树求解

class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        Queue<TreeNode> que = new LinkedList();
        que.offer(root);
        int count = 0;
        while(!que.isEmpty()){
            int size = que.size();
            while(size-->0){
                count ++;
                TreeNode temp =que.poll();
                if(temp.left!=null) que.offer(temp.left);
                if(temp.right !=null) que.offer(temp.right);
            }
        }
        return count;
    }
}

110. 平衡二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public boolean isBalanced(TreeNode root) {
        return getHeigth(root) != -1;
    }
    public int getHeigth(TreeNode node){
        if(node == null) return 0;
        int leftheigth = getHeigth(node.left);
        if(leftheigth == -1) return -1;
        int rightheigth = getHeigth(node.right);
        if(rightheigth == -1) return -1;
        if(Math.abs(leftheigth-rightheigth) > 1) return -1;
        return Math.max(leftheigth,rightheigth)+1;
    }
}

257. 二叉树的所有路径 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        ArrayList<String> res = new ArrayList<>();
        if(root == null) return res;
        ArrayList<Integer> path = new ArrayList();
        DFS(root,res,path);
        return res;
    }
    public void DFS(TreeNode root, List<String> res,List<Integer> path){
        path.add(root.val);
        if(root.left == null && root.right == null){
            StringBuilder str = new StringBuilder();
            for(int i = 0; i< path.size()-1;i++){
                str.append(path.get(i) + "->");
            }
            str.append(path.get(path.size()-1));
            res.add(str.toString());
        }
        if(root.left != null) {
            DFS(root.left,res,path);
            path.remove(path.size()-1);
        }
            
        if(root.right != null){
            DFS(root.right,res,path);
            path.remove(path.size()-1);
        } 
    }
    
}

100. 相同的树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p == null && q== null) return true;
        if(p == null || q == null) return false;
        if(p.val != q.val) return false;
        boolean leftcompare = isSameTree(p.left,q.left);
        boolean rigthconpaer = isSameTree(p.right,q.right);
        return leftcompare && rigthconpaer;
    }
}

Loading Question… - 力扣(LeetCode) (leetcode-cn.com)

通过递归求取左子树左叶子之和,和右子树左叶子之和,相加便是整个树的左叶子之和。

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if(root == null) return 0;
        int leftsum = sumOfLeftLeaves(root.left);
        int rightsum = sumOfLeftLeaves(root.right);

        int mid = 0;
        //叶子节点
        if(root.left != null && root.left.left == null &&root.left.right == null){
            mid = root.left.val;
        }
        int sum = mid + leftsum + rightsum;
        return sum;
    }
}
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if(root == null) return 0;
        Stack<TreeNode> stack =new  Stack<>();
        stack.add(root);
        int res = 0;
        while(!stack.isEmpty()){
            TreeNode temp = stack.pop();
            if(temp.left != null&& temp.left.left == null && temp.left.right == null){
                res += temp.left.val;
            }
            if(temp.left != null) stack.add(temp.left);
            if(temp.right != null) stack.add(temp.right);
        }
        return res;
    }
}

513. 找树左下角的值 - 力扣(LeetCode) (leetcode-cn.com)

在树的最后一行找到最左边的值。深度最大的叶子节点一定是最后一行

class Solution {
    private int depth = -1;
    private int value = 0;
    public int findBottomLeftValue(TreeNode root) {
        value = root.val;
        dfs(root,0);
        return value;

    }
    public void dfs(TreeNode node,int deep){
        if(node == null) return;
        if(node.left == null && node.right == null){
            if(deep > depth){
                depth = deep;
                value = node.val;
            }
        }
        if(node.left != null) dfs(node.left,deep+1);
        if(node.right != null) dfs(node.right,deep+1);
    }
}
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        if(root == null) return -1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int res =0;
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size-->0){
                TreeNode temp = queue.poll();
                res = temp.val;
                if(temp.right != null) queue.offer(temp.right);
                if(temp.left != null) queue.offer(temp.left);
                
            }
        }
        return res;
    }
}

112. 路径总和 - 力扣(LeetCode) (leetcode-cn.com)

寻找其中一天路径,递归需要返回值

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        targetSum -= root.val;
        if(root.left == null && root.right == null && targetSum  == 0) return true;
        if(root.left != null){
            boolean left = hasPathSum(root.left,targetSum);;
            if(left) return true;
        } 
        if(root.right != null){
            boolean right = hasPathSum(root.right,targetSum);;
            if(right) return true;
        }
        return false;
    }
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<Integer> s2 = new Stack<>();
        s1.push(root);
        s2.push(root.val);
        while(!s1.isEmpty()){
            int size = s1.size();
            while(size-- > 0){
                TreeNode node = s1.pop();
                int sum = s2.pop();
                if(node.left ==null && node.right ==null &&sum == targetSum) return true;
                if(node.left!=null) {
                    s1.push(node.left);
                    s2.push(sum + node.left.val);
                } 
                if(node.right!=null) {
                    s1.push(node.right);
                    s2.push(sum + node.right.val);
                } 
            }
            
        }
        return false;
    }
}

113. 路径总和 II - 力扣(LeetCode) (leetcode-cn.com)

找到所有的路径,递归不需要返回值

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();
        if(root == null) return res;
        List<Integer> path = new ArrayList<>();
        dfs(root,targetSum,path,res);
        return res;
    }
    public void dfs(TreeNode root,int targetSum,List<Integer> path,List<List<Integer>> res){
        path.add(root.val);
        if(root.left == null && root.right == null && targetSum  - root.val == 0){
            res.add(new ArrayList(path));
        }
        if(root.left != null) {
            dfs(root.left,targetSum-root.val,path,res);
            path.remove(path.size()-1);
        }
        if(root.right != null) {
            dfs(root.right,targetSum-root.val,path,res);
            path.remove(path.size()-1);
        }
    }
}

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

注意区间都是左闭右闭

class Solution {
    private Map<Integer,Integer> map = new HashMap<Integer,Integer>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        int n = inorder.length;
        for(int i =0;i<n;i++){
            map.put(inorder[i],i);
        }
        return dfs(inorder,postorder,0,n-1,0,n-1);     
    }
    public TreeNode dfs(int[] inorder,int[] postorder,int il,int ir,int pl, int pr){
        if(pl > pr) return null;
        int index = map.get(postorder[pr]);
        TreeNode root = new TreeNode(postorder[pr]);
        root.left = dfs(inorder,postorder,il,index-1,pl,pl+index-il-1);
        root.right = dfs(inorder,postorder,index+1,ir,pl+index-il,pr-1);
        return root;
    } 
}

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    private Map<Integer,Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int n  = inorder.length;
        for(int i = 0;i< n;i++){
            map.put(inorder[i],i);
        }
        return dfs(preorder,inorder,0,n-1,0,n-1);
    }
    public TreeNode dfs(int[] preorder,int[] inorder,int prestart,int preend,int instart,int inend){
        if(prestart > preend) return null;
        int index = map.get(preorder[prestart]);
        TreeNode root = new TreeNode(preorder[prestart]);
        root.left = dfs(preorder,inorder,prestart+1,prestart+index-instart,instart,index-1);
        root.right = dfs(preorder,inorder,prestart+index-instart+1,preend,index+1,inend-1);
        return root;
    }
}

654. 最大二叉树 - 力扣(LeetCode) (leetcode-cn.com)

区间也是左闭右闭

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return dfs(nums,0,nums.length-1);
    }
    public TreeNode dfs(int[] nums,int leftindex,int rightindex){
        if(leftindex> rightindex) return null;
        int maxindex = leftindex;
        int maxval = nums[maxindex];
        for(int i = leftindex+1;i<=rightindex;i++){
            if(nums[i] > maxval){
                maxval = nums[i];
                maxindex = i;
            }
        }
        TreeNode root = new TreeNode(maxval);
        root.left = dfs(nums,leftindex,maxindex-1);
        root.right = dfs(nums,maxindex+1,rightindex);
        return root;
    }
}

617. 合并二叉树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;

        TreeNode newRoot = new TreeNode(root1.val + root2.val);
        newRoot.left = mergeTrees(root1.left,root2.left);
        newRoot.right = mergeTrees(root1.right,root2.right);
        return newRoot;
    }
}
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;
        Stack<TreeNode> stack = new Stack();
        stack.push(root2);
        stack.push(root1);
        while(!stack.isEmpty()){
            TreeNode node1 = stack.pop();
            TreeNode node2 = stack.pop();
            node1.val = node1.val + node2.val;
            if(node2.right!=null && node1.right!=null) {
                stack.push(node2.right);
                stack.push(node1.right);
            }else{
                if(node1.right == null){
                    node1.right = node2.right;
                }
            }
            if(node2.left!=null && node1.left!=null) {
                stack.push(node2.left);
                stack.push(node1.left);
            }else{
                if(node1.left == null){
                    node1.left = node2.left;
                }
            }
        }
       return root1;
    }
}

Loading Question… - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val) return root;
        if(root.val > val)return searchBST(root.left,val);
        else  return searchBST(root.right,val);
    }
}

98. 验证二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    long pre = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        //左中右遍历
        if(root == null) return true;
        if(!isValidBST(root.left)) return false; //判断所有左子树是否正确
        if(pre >= root.val) return false; //如果前一个数大于后一个数,则返回false;
        pre = root.val;
        return isValidBST(root.right); //判断右子树是否正确
    }
}

530. 二叉搜索树的最小绝对差 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    TreeNode pre;
    int res = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root == null) return 0;
        dfs(root);
        return res;
    }
    public void dfs(TreeNode root){
        if(root == null) return;
        dfs(root.left);//遍历左边
        if(pre != null) res = Math.min(res,root.val-pre.val);//比较出最小值
        pre = root;
        dfs(root.right);//右边
    }
}
class Solution {
    int res = Integer.MAX_VALUE;
    TreeNode pre;
    public int getMinimumDifference(TreeNode root) {
        if(root == null) return 0;
        Stack<TreeNode> stack = new Stack<>();//左节点
        stack.push(root);
        TreeNode cur = root;
        while(!stack.isEmpty() || cur!= null){//如果栈不为空,或者当前节点不为空
            if(cur != null){//如果当前节点不为空,就继续找他的左节点,如果为空了就证明上一个节点为左节点
                stack.push(cur);
                cur = cur.left;
            }else{//找到空节点的上一个节点
                cur = stack.pop();
                if(pre != null)//当前一个节点不为空的时候
                    res = Math.min(res,cur.val-pre.val);//比较
                pre = cur;//把当前节点赋值到前一个节点
                cur = cur.right;//寻找当前节点的右节点进行对比
            }

        }
        return res;
    }

}

501. 二叉搜索树中的众数 - 力扣(LeetCode) (leetcode-cn.com)

暴力搜素

class Solution {
    public int[] findMode(TreeNode root) {
        Map<Integer,Integer> map = new HashMap<>();
        List<Integer> res = new ArrayList<>();
        if(root == null) return res.stream().mapToInt(Integer::intValue).toArray();
        search(root,map);
        List<Map.Entry<Integer,Integer>> entry = map.entrySet().stream().sorted((o1,o2) -> o2.getValue().compareTo(o1.getValue()))
                                                    .collect(Collectors.toList());
        //把最高频率加入res
        res.add(entry.get(0).getKey());
        for(int i = 1; i< entry.size();i++){
            if(entry.get(i).getValue() == entry.get(i-1).getValue()){
                res.add(entry.get(i).getKey());
            }else break;
        }
        return res.stream().mapToInt(Integer::intValue).toArray();
        
    }
    public void search(TreeNode cur,Map<Integer,Integer> map){
        if(cur == null) return;
        map.put(cur.val,map.getOrDefault(cur.val,0)+1);
        search(cur.left,map);
        search(cur.right,map);
    }
}

class Solution {
    ArrayList<Integer> res;
    int maxcount;
    int count;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
        res = new ArrayList();
        maxcount = 0;
        count = 0;
        pre = null;
        dfs(root);
        return res.stream().mapToInt(Integer::valueOf).toArray();

    }
    public void dfs(TreeNode node){
        if(node == null) return;
        dfs(node.left);
        int nodeval = node.val;
        if(pre == null || nodeval != pre.val) count = 1;
        else count ++;
        if(count > maxcount){
            res.clear();//清空
            res.add(nodeval);
            maxcount = count;
        }else if(count == maxcount){
            res.add(nodeval);
        }
        pre = node;
        dfs(node.right);
    }
}

class Solution {
    ArrayList<Integer> res;
    int maxcount;
    int count;
    public int[] findMode(TreeNode root) {
        res = new ArrayList();
        maxcount = 0;
        count = 0;
        TreeNode pre = null;
        TreeNode cur = root;
        Stack<TreeNode> stack = new Stack();
        while(!stack.isEmpty() || cur != null){
            if(cur != null){
                stack.push(cur);
                cur = cur.left;
            }else{
                cur = stack.pop();
                if(pre == null || cur.val != pre.val){
                    count = 1;
                }else{
                    count ++;
                }
                if(count > maxcount){
                    res.clear();
                    res.add(cur.val);
                    maxcount = count;
                }else if(count == maxcount){
                    res.add(cur.val);
                }
                pre = cur;
                cur = cur.right;
            }
        }
        return res.stream().mapToInt(Integer::valueOf).toArray();
    }
}

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return root;
        while(true){
            if(root.val > p.val && root.val > q.val) root = root.left;
            else if(root.val < p.val && root.val < q.val) root = root.right;
            else  break;
        }
        return root;
    }
}

236. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if(left == null && right == null) return null;
        else if(left != null && right == null) return left;
        else if(left == null && right!= null) return right;
        else return root;
    }
}

Loading Question… - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) return new TreeNode(val);
        TreeNode pre = null;
        TreeNode temp = root; //缓存root
        while(root != null){//找到插入的位置
            pre = root;
            if(root.val > val) root = root.left;
            else if(root.val < val) root = root.right;
        }
        //进行插入
        if(pre.val > val) pre.left = new TreeNode(val);
        else pre.right = new TreeNode(val);
        return temp;
    }
}

450. 删除二叉搜索树中的节点 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null) return null;
        if(root.val > key) root.left =  deleteNode(root.left,key);
        else if(root.val < key)root.right =  deleteNode(root.right,key);
        else{
            if(root.left == null && root.right == null) root = null;
            else if(root.left != null && root.right == null) return root.left;
            else if(root.right != null && root.left == null) return root.right;
            else if(root.right != null && root.left != null){
                TreeNode cur = root.right;
                while(cur.left != null){
                    cur = cur.left;
                }
                cur.left = root.left;
                root = root.right;
            }
        }
        return root;
    }
}

669. 修剪二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) {
            return null;
        }
        if (root.val < low) {
            //节点比low小,就把左节点全部裁掉.
            root = root.right;
            //裁掉之后,继续看右节点的剪裁情况.剪裁后重新赋值给root.
            root = trimBST(root, low, high);
        } else if (root.val > high) {
            //如果high大,就把右节点全部裁掉.
            root = root.left;
            //裁掉之后,继续看左节点的剪裁情况
            root = trimBST(root, low, high);
        } else {
            //如果数字在区间内,就去裁剪左右子节点.
            root.left = trimBST(root.left, low, high);
            root.right = trimBST(root.right, low, high);
        }
        return root;
    }
}

108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return dfs(nums,0,nums.length-1);
    }
    public TreeNode dfs(int[] nums,int start,int end){
        if(start > end) return null;
        int mid = start + (end - start)/2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = dfs(nums,start,mid-1);
        root.right = dfs(nums,mid+1,end);
        return root;
    }
}

538. 把二叉搜索树转换为累加树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    int sum =0;
    public TreeNode convertBST(TreeNode root) {
        if(root != null){
            convertBST(root.right);
            sum += root.val;
            root.val = sum;
            convertBST(root.left);
            return root;
        }
        return root;
    }
}

trimBST(root.right, low, high);
}
return root;
}
}


[108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/)

```java
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return dfs(nums,0,nums.length-1);
    }
    public TreeNode dfs(int[] nums,int start,int end){
        if(start > end) return null;
        int mid = start + (end - start)/2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = dfs(nums,start,mid-1);
        root.right = dfs(nums,mid+1,end);
        return root;
    }
}

538. 把二叉搜索树转换为累加树 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
    int sum =0;
    public TreeNode convertBST(TreeNode root) {
        if(root != null){
            convertBST(root.right);
            sum += root.val;
            root.val = sum;
            convertBST(root.left);
            return root;
        }
        return root;
    }
}
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小七rrrrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值