关于二叉树的算法总结
文章目录
二叉树的种类
满二叉树
满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。
这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节点的二叉树。
完全二叉树
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
二叉搜索树
二叉搜索树是一个有序树。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树
[3,5,6,10,11,15,17]
平衡二叉搜索树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉树的存储方式
数组存储方式的分析
- 优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。
- 缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低
链式存储方式的分析
- 优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。
- 缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)
树存储方式的分析能
提高数据存储,读取的效率, 比如利用二叉排序树(Binary Sort Tree),既可以保证数据的检索速度,同时也可以保证数据的插入,删除,修改的速度。
二叉树的遍遍历方式
二叉树主要有两种遍历方式:
- 深度优先遍历:先往深走,遇到叶子节点再往回走。
- 前序遍历(递归法,迭代法)
- 中序遍历(递归法,迭代法)
- 后序遍历(递归法,迭代法)
- 广度优先遍历:一层一层的去遍历。
- 层次遍历(迭代法)
深度优先遍历
- 前序遍历:中左右
- 中序遍历:左中右
- 后序遍历:左右中
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;
}
}