目录
本文中二叉树的定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
二叉树的中序遍历(medium难度)
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
inorder(root, res);
return res;
}
public void inorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
inorder(root.left, res);
res.add(root.val);
inorder(root.right, res);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
Deque<TreeNode> stk = new LinkedList<TreeNode>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
TreeNode predecessor = null;
while (root != null) {
if (root.left != null) {
// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root.left;
while (predecessor.right != null && predecessor.right != root) {
predecessor = predecessor.right;
}
// 让 predecessor 的右指针指向 root,继续遍历左子树
if (predecessor.right == null) {
predecessor.right = root;
root = root.left;
}
// 说明左子树已经访问完了,我们需要断开链接
else {
res.add(root.val);
predecessor.right = null;
root = root.right;
}
}
// 如果没有左孩子,则直接访问右孩子
else {
res.add(root.val);
root = root.right;
}
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/
来源:力扣(LeetCode)
二叉树的中序遍历(medium难度)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
preorder(root, res);
return res;
}
public void preorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
res.add(root.val);
preorder(root.left, res);
preorder(root.right, res);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
TreeNode p1 = root, p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
res.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
}
} else {
res.add(p1.val);
}
p1 = p1.right;
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
二叉树的后序遍历(medium难度)
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
postorder(root, res);
return res;
}
public void postorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
postorder(root.left, res);
postorder(root.right, res);
res.add(root.val);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode prev = null;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.right == null || root.right == prev) {
res.add(root.val);
prev = root;
root = null;
} else {
stack.push(root);
root = root.right;
}
}
return res;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
TreeNode p1 = root, p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
addPath(res, p1.left);
}
}
p1 = p1.right;
}
addPath(res, root);
return res;
}
public void addPath(List<Integer> res, TreeNode node) {
int count = 0;
while (node != null) {
++count;
res.add(node.val);
node = node.right;
}
int left = res.size() - count, right = res.size() - 1;
while (left < right) {
int temp = res.get(left);
res.set(left, res.get(right));
res.set(right, temp);
left++;
right--;
}
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
二叉树的层序遍历(medium难度)
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
与本题相同的题目:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (root == null) {
return ret;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> level = new ArrayList<Integer>();
int currentLevelSize = queue.size();
for (int i = 1; i <= currentLevelSize; ++i) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
ret.add(level);
}
return ret;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-xu-bian-li-by-leetcode-solution/
来源:力扣(LeetCode)
自己的代码:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return new ArrayList<>();
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int len = queue.size();
List<Integer> temp = new ArrayList<>();
for(int i = 0; i <len; i++){
TreeNode node = queue.poll();
temp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
res.add(temp);
}
return res;
}
}
二叉树的层序遍历Ⅱ(simple难度)
https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> levelOrder = new LinkedList<List<Integer>>();
if (root == null) {
return levelOrder;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> level = new ArrayList<Integer>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
TreeNode left = node.left, right = node.right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}
}
levelOrder.add(0, level);
}
return levelOrder;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/solution/er-cha-shu-de-ceng-ci-bian-li-ii-by-leetcode-solut/
来源:力扣(LeetCode)
也可以直接把res集合反转
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if(root==null) {
return new ArrayList<List<Integer>>();
}
//用来存放最终结果
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
//创建一个队列,将根节点放入其中
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()) {
//每次遍历的数量为队列的长度
int size = queue.size();
ArrayList<Integer> tmp = new ArrayList<Integer>();
//将这一层的元素全部取出,放入到临时数组中,如果节点的左右孩子不为空,继续放入队列
for(int i=0;i<size;++i) {
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left!=null) {
queue.offer(node.left);
}
if(node.right!=null) {
queue.offer(node.right);
}
}
res.add(tmp);
}
//翻转最终结果并返回
Collections.reverse(res);
return res;
}
}
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/solution/san-chong-shi-xian-tu-jie-107er-cha-shu-de-ceng-ci/
来源:力扣(LeetCode)
自己的代码:
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if(root ==null){
return new ArrayList<>();
}
List<List<Integer>> res = new ArrayList<>();
Queue<TreeNode>queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList<>();
int len = queue.size();
for(int i = 0 ;i < len ; i++){
TreeNode node = queue.poll();
temp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
res.add(0,temp);
}
return res;
}
}
填充每个节点的下一个右侧节点指针(medium难度)
https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/
本方法思路及代码来源:
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/dong-hua-yan-shi-san-chong-shi-xian-116-tian-chong/
来源:力扣(LeetCode)
class Solution {
public Node connect(Node root) {
if(root==null) {
return root;
}
LinkedList<Node> queue = new LinkedList<Node>();
queue.add(root);
while(queue.size()>0) {
int size = queue.size();
//将队列中的元素串联起来
Node tmp = queue.get(0);
for(int i=1;i<size;++i) {
tmp.next = queue.get(i);
tmp = queue.get(i);
}
//遍历队列中的每个元素,将每个元素的左右节点也放入队列中
for(int i=0;i<size;++i) {
tmp = queue.remove();
if(tmp.left!=null) {
queue.add(tmp.left);
}
if(tmp.right!=null) {
queue.add(tmp.right);
}
}
}
return root;
}
}
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/dong-hua-yan-shi-san-chong-shi-xian-116-tian-chong/
来源:力扣(LeetCode)
class Solution {
public Node connect(Node root) {
if(root==null) {
return root;
}
Node pre = root;
//循环条件是当前节点的left不为空,当只有根节点
//或所有叶子节点都出串联完后循环就退出了
while(pre.left!=null) {
Node tmp = pre;
while(tmp!=null) {
//将tmp的左右节点都串联起来
//注:外层循环已经判断了当前节点的left不为空
tmp.left.next = tmp.right;
//下一个不为空说明上一层已经帮我们完成串联了
if(tmp.next!=null) {
tmp.right.next = tmp.next.left;
}
//继续右边遍历
tmp = tmp.next;
}
//从下一层的最左边开始遍历
pre = pre.left;
}
return root;
}
}
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/dong-hua-yan-shi-san-chong-shi-xian-116-tian-chong/
来源:力扣(LeetCode)
class Solution {
public Node connect(Node root) {
dfs(root);
return root;
}
void dfs(Node root) {
if(root==null) {
return;
}
Node left = root.left;
Node right = root.right;
//配合动画演示理解这段,以root为起点,将整个纵深这段串联起来
while(left!=null) {
left.next = right;
left = left.right;
right = right.left;
}
//递归的调用左右节点,完成同样的纵深串联
dfs(root.left);
dfs(root.right);
}
}
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/dong-hua-yan-shi-san-chong-shi-xian-116-tian-chong/
来源:力扣(LeetCode)
我的代码:
class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int len = queue.size();
Node cur = null;
for (int i = 0; i < len; i++) {
Node node = queue.poll();
if(cur != null){
cur.next = node;
}
cur = node;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
cur = null;
}
return root;
}
}
填充每个节点的下一个右侧节点指针Ⅱ(medium难度)
https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/
代码如下:
public void levelOrder(TreeNode tree) {
if (tree == null)
return;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(tree);//相当于把数据加入到队列尾部
while (!queue.isEmpty()) {
//poll方法相当于移除队列头部的元素
TreeNode node = queue.poll();
System.out.println(node.val);
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/solution/bfsjie-jue-zui-hao-de-ji-bai-liao-100de-yong-hu-by/
来源:力扣(LeetCode)
public Node connect(Node root) {
if (root == null)
return root;
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
//每一层的数量
int levelCount = queue.size();
//前一个节点
Node pre = null;
for (int i = 0; i < levelCount; i++) {
//出队
Node node = queue.poll();
//如果pre为空就表示node节点是这一行的第一个,
//没有前一个节点指向他,否则就让前一个节点指向他
if (pre != null) {
pre.next = node;
}
//然后再让当前节点成为前一个节点
pre = node;
//左右子节点如果不为空就入队
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
return root;
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/solution/bfsjie-jue-zui-hao-de-ji-bai-liao-100de-yong-hu-by/
来源:力扣(LeetCode)
public Node connect(Node root) {
if (root == null)
return root;
//cur我们可以把它看做是每一层的链表
Node cur = root;
Node dummy = new Node(0);
while (cur != null) {
dummy.next = null;//避免死循环
//遍历当前层的时候,为了方便操作在下一
//层前面添加一个哑结点(注意这里是访问
//当前层的节点,然后把下一层的节点串起来)
//pre表示访下一层节点的前一个节点
Node pre = dummy;
//然后开始遍历当前层的链表
while (cur != null) {
if (cur.left != null) {
//如果当前节点的左子节点不为空,就让pre节点
//的next指向他,也就是把它串起来
pre.next = cur.left;
//然后再更新pre
pre = pre.next;
}
//同理参照左子树
if (cur.right != null) {
pre.next = cur.right;
pre = pre.next;
}
//继续访问这样行的下一个节点
cur = cur.next;
}
//把下一层串联成一个链表之后,让他赋值给cur,
//后续继续循环,直到cur为空为止
cur = dummy.next;
}
return root;
}
我的代码:
class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int len = queue.size();
Node cur = null;
for (int i = 0; i < len; i++) {
Node node = queue.poll();
if(cur != null){
cur.next = node;
}
cur = node;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
cur = null;
}
return root;
}
}
二叉树的右视图(medium难度)
https://leetcode-cn.com/problems/binary-tree-right-side-view/
本方法思路及代码来源:
作者:sweetiee
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/solution/jian-dan-bfsdfs-bi-xu-miao-dong-by-sweetiee/
来源:力扣(LeetCode)
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
if (i == size - 1) { //将当前层的最后一个节点放入结果列表
res.add(node.val);
}
}
}
return res;
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/solution/jian-dan-bfsdfs-bi-xu-miao-dong-by-sweetiee/
来源:力扣(LeetCode)
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
dfs(root, 0); // 从根节点开始访问,根节点深度是0
return res;
}
private void dfs(TreeNode root, int depth) {
if (root == null) {
return;
}
// 先访问 当前节点,再递归地访问 右子树 和 左子树。
if (depth == res.size()) { // 如果当前节点所在深度还没有出现在res里,说明在该深度下当前节点是第一个被访问的节点,因此将当前节点加入res中。
res.add(root.val);
}
depth++;
dfs(root.right, depth);
dfs(root.left, depth);
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/solution/jian-dan-bfsdfs-bi-xu-miao-dong-by-sweetiee/
来源:力扣(LeetCode)
我的代码:
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode node = queue.poll();
if(i == len-1){
res.add(node.val);
}
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
return res;
}
}
二叉树的层平均值(simple难度)
https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Integer> counts = new ArrayList<Integer>();
List<Double> sums = new ArrayList<Double>();
dfs(root, 0, counts, sums);
List<Double> averages = new ArrayList<Double>();
int size = sums.size();
for (int i = 0; i < size; i++) {
averages.add(sums.get(i) / counts.get(i));
}
return averages;
}
public void dfs(TreeNode root, int level, List<Integer> counts, List<Double> sums) {
if (root == null) {
return;
}
if (level < sums.size()) {
sums.set(level, sums.get(level) + root.val);
counts.set(level, counts.get(level) + 1);
} else {
sums.add(1.0 * root.val);
counts.add(1);
}
dfs(root.left, level + 1, counts, sums);
dfs(root.right, level + 1, counts, sums);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/solution/er-cha-shu-de-ceng-ping-jun-zhi-by-leetcode-soluti/
来源:力扣(LeetCode)
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> averages = new ArrayList<Double>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
double sum = 0;
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
sum += node.val;
TreeNode left = node.left, right = node.right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}
}
averages.add(sum / size);
}
return averages;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/solution/er-cha-shu-de-ceng-ping-jun-zhi-by-leetcode-soluti/
来源:力扣(LeetCode)
我的代码:
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new ArrayList<>();
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
double sum = 0;
int len = queue.size();
for (int i = 0; i < len; i++) {
TreeNode node = queue.poll();
sum += node.val;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
res.add(sum/len);
}
return res;
}
}
对称二叉树(simple难度)
https://leetcode-cn.com/problems/symmetric-tree/
与本题相同题目:
本文思路及解法参考了《剑指offer28.对称的二叉树》的题解
作者:jyd
链接:https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/solution/mian-shi-ti-28-dui-cheng-de-er-cha-shu-di-gui-qing/
来源:力扣(LeetCode)
方法一:递归
class Solution {
public boolean isSymmetric(TreeNode root) {
return root == null ? true : recur(root.left, root.right);
}
boolean recur(TreeNode L, TreeNode R) {
if(L == null && R == null) return true;
if(L == null || R == null || L.val != R.val) return false;
return recur(L.left, R.right) && recur(L.right, R.left);
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/solution/mian-shi-ti-28-dui-cheng-de-er-cha-shu-di-gui-qing/
来源:力扣(LeetCode)
方法二:迭代(效率低于递归)
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
首先引入一个队列,这是把递归程序改写成迭代程序的常用方法。
初始化时把根节点入队两次。每次提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像),
然后将两个结点的左右子结点按相反的顺序插入队列中。
当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root, root);
}
public boolean check(TreeNode u, TreeNode v) {
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.offer(u);
q.offer(v);
while (!q.isEmpty()) {
u = q.poll();
v = q.poll();
if (u == null && v == null) {
continue;
}
if ((u == null || v == null) || (u.val != v.val)) {
return false;
}
q.offer(u.left);
q.offer(v.right);
q.offer(u.right);
q.offer(v.left);
}
return true;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/symmetric-tree/solution/dui-cheng-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
二叉树的最大深度(simple难度)
https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
与本题相同题目:
本文思路及解法参考了《剑指offer55-Ⅰ.二叉树的深度》的题解
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
List<TreeNode> queue = new LinkedList<>() {{ add(root); }}, tmp;
int res = 0;
while(!queue.isEmpty()) {
tmp = new LinkedList<>();
for(TreeNode node : queue) {
if(node.left != null) tmp.add(node.left);
if(node.right != null) tmp.add(node.right);
}
queue = tmp;
res++;
}
return res;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
二叉树最小深度(simple难度)
https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
本方法思路及代码来源:
作者:reals
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/solution/li-jie-zhe-dao-ti-de-jie-shu-tiao-jian-by-user7208/
来源:力扣(LeetCode)
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
//这道题递归条件里分为三种情况
//1.左孩子和有孩子都为空的情况,说明到达了叶子节点,直接返回1即可
if(root.left == null && root.right == null) return 1;
//2.如果左孩子和由孩子其中一个为空,那么需要返回比较大的那个孩子的深度
int m1 = minDepth(root.left);
int m2 = minDepth(root.right);
//这里其中一个节点为空,说明m1和m2有一个必然为0,所以可以返回m1 + m2 + 1;
if(root.left == null || root.right == null) return m1 + m2 + 1;
//3.最后一种情况,也就是左右孩子都不为空,返回最小深度+1即可
return Math.min(m1,m2) + 1;
}
}
作者:reals
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/solution/li-jie-zhe-dao-ti-de-jie-shu-tiao-jian-by-user7208/
来源:力扣(LeetCode)
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
int m1 = minDepth(root.left);
int m2 = minDepth(root.right);
//1.如果左孩子和右孩子有为空的情况,直接返回m1+m2+1
//2.如果都不为空,返回较小深度+1
return root.left == null || root.right == null ? m1 + m2 + 1 : Math.min(m1,m2) + 1;
}
}
作者:reals
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/solution/li-jie-zhe-dao-ti-de-jie-shu-tiao-jian-by-user7208/
来源:力扣(LeetCode)
翻转二叉树(simple难度)
https://leetcode-cn.com/problems/invert-binary-tree/
与本题相同的题目:
本文思路及解法参考了《剑指offer27.二叉树的镜像》的题解
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return null;
TreeNode tmp = root.left;
root.left = invertTree(root.right);
root.right = invertTree(tmp);
return root;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>() {{ add(root); }};
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if(node.left != null) stack.add(node.left);
if(node.right != null) stack.add(node.right);
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
return root;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
完全二叉树的节点个数(medium难度)
二叉树求节点个数通用递归解法:
DFS:
class Solution {
public int countNodes(TreeNode root) {
if (root == null) return 0;
int leftNum = countNodes(root.left); // 左
int rightNum = countNodes(root.right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
}
一行代码:
public int countNodes(TreeNode root) {
return root == null ? 0 : countNodes(root.left) + countNodes(root.right) + 1;
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/javadai-ma-tu-wen-xiang-jie-ji-bai-liao-100de-yong/
来源:力扣(LeetCode)
本题方法和代码来源:
作者:sdwwld
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/javadai-ma-tu-wen-xiang-jie-ji-bai-liao-100de-yong/
来源:力扣(LeetCode)
根据完全二叉树的特性的高效率解法:
public int countNodes(TreeNode root) {
//计算树的高度,
int height = treeHeight(root);
//如果树是空的,或者高度是1,直接返回
if (height == 0 || height == 1)
return height;
//如果右子树的高度是树的高度减1,说明左子树是满二叉树,
//左子树可以通过公式计算,只需要递归右子树就行了
if (treeHeight(root.right) == height - 1) {
//注意这里的计算,左子树的数量是实际上是(1 << (height - 1))-1,
//不要把根节点给忘了,在加上1就是(1 << (height - 1))
return (1 << (height - 1)) + countNodes(root.right);
} else {
//如果右子树的高度不是树的高度减1,说明右子树是满二叉树,可以通过
//公式计算右子树,只需要递归左子树就行了
return (1 << (height - 2)) + countNodes(root.left);
}
}
//计算树的高度
private int treeHeight(TreeNode root) {
return root == null ? 0 : 1 + treeHeight(root.left);
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/javadai-ma-tu-wen-xiang-jie-ji-bai-liao-100de-yong/
来源:力扣(LeetCode)
平衡二叉树(simple难度)
本题方法和代码来源:
作者:jyd
链接:https://leetcode-cn.com/problems/balanced-binary-tree/solution/balanced-binary-tree-di-gui-fang-fa-by-jin40789108/
来源:力扣(LeetCode)
class Solution {
public boolean isBalanced(TreeNode root) {
return recur(root) != -1;
}
private int recur(TreeNode root) {
if (root == null) return 0;
int left = recur(root.left);
if(left == -1) return -1;
int right = recur(root.right);
if(right == -1) return -1;
return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/balanced-binary-tree/solution/balanced-binary-tree-di-gui-fang-fa-by-jin40789108/
来源:力扣(LeetCode)
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) return true;
return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int depth(TreeNode root) {
if (root == null) return 0;
return Math.max(depth(root.left), depth(root.right)) + 1;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/balanced-binary-tree/solution/balanced-binary-tree-di-gui-fang-fa-by-jin40789108/
来源:力扣(LeetCode)
从中序与后序遍历序列构造二叉树(medium)
https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
本题方法和代码来源:
作者:reals
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/solution/tu-jie-gou-zao-er-cha-shu-wei-wan-dai-xu-by-user72/
来源:力扣(LeetCode)
class Solution {
HashMap<Integer,Integer> memo = new HashMap<>();
int[] post;
public TreeNode buildTree(int[] inorder, int[] postorder) {
for(int i = 0;i < inorder.length; i++) memo.put(inorder[i], i);
post = postorder;
TreeNode root = buildTree(0, inorder.length - 1, 0, post.length - 1);
return root;
}
public TreeNode buildTree(int is, int ie, int ps, int pe) {
if(ie < is || pe < ps) return null;
int root = post[pe];
int ri = memo.get(root);
TreeNode node = new TreeNode(root);
node.left = buildTree(is, ri - 1, ps, ps + ri - is - 1);
node.right = buildTree(ri + 1, ie, ps + ri - is, pe - 1);
return node;
}
}
作者:reals
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/solution/tu-jie-gou-zao-er-cha-shu-wei-wan-dai-xu-by-user72/
来源:力扣(LeetCode)
从前序与中序遍历序列构造二叉树(medium难度)
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
本题方法和代码来源:
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/qian-xu-bian-li-python-dai-ma-java-dai-ma-by-liwei/
来源:力扣(LeetCode)
import java.util.HashMap;
import java.util.Map;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
private int[] preorder;
private Map<Integer, Integer> hash;
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen) {
throw new RuntimeException("Incorrect input data.");
}
this.preorder = preorder;
this.hash = new HashMap<>();
for (int i = 0; i < inLen; i++) {
hash.put(inorder[i], i);
}
return buildTree(0, preLen - 1, 0, inLen - 1);
}
private TreeNode buildTree(int preLeft, int preRight, int inLeft, int inRight) {
// 因为是递归调用的方法,按照国际惯例,先写递归终止条件
if (preLeft > preRight || inLeft > inRight) {
return null;
}
// 先序遍历的起点元素很重要
int pivot = preorder[preLeft];
TreeNode root = new TreeNode(pivot);
int pivotIndex = hash.get(pivot);
root.left = buildTree(preLeft + 1, pivotIndex - inLeft + preLeft,
inLeft, pivotIndex - 1);
root.right = buildTree(pivotIndex - inLeft + preLeft + 1, preRight,
pivotIndex + 1, inRight);
return root;
}
}
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/qian-xu-bian-li-python-dai-ma-java-dai-ma-by-liwei/
来源:力扣(LeetCode)
最大二叉树(medium难度)
https://leetcode-cn.com/problems/maximum-binary-tree/
public class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return construct(nums, 0, nums.length);
}
public TreeNode construct(int[] nums, int l, int r) {
if (l == r)
return null;
int max_i = max(nums, l, r);
TreeNode root = new TreeNode(nums[max_i]);
root.left = construct(nums, l, max_i);
root.right = construct(nums, max_i + 1, r);
return root;
}
public int max(int[] nums, int l, int r) {
int max_i = l;
for (int i = l; i < r; i++) {
if (nums[max_i] < nums[i])
max_i = i;
}
return max_i;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/maximum-binary-tree/solution/zui-da-er-cha-shu-by-leetcode/
来源:力扣(LeetCode)
左叶子之和(simple难度)
https://leetcode-cn.com/problems/sum-of-left-leaves/
深度优先搜索:
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
return root != null ? dfs(root) : 0;
}
public int dfs(TreeNode node) {
int ans = 0;
if (node.left != null) {
ans += isLeafNode(node.left) ? node.left.val : dfs(node.left);
}
if (node.right != null && !isLeafNode(node.right)) {
ans += dfs(node.right);
}
return ans;
}
public boolean isLeafNode(TreeNode node) {
return node.left == null && node.right == null;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/sum-of-left-leaves/solution/zuo-xie-zi-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
广度优先搜索:
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
int ans = 0;
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node.left != null) {
if (isLeafNode(node.left)) {
ans += node.left.val;
} else {
queue.offer(node.left);
}
}
if (node.right != null) {
if (!isLeafNode(node.right)) {
queue.offer(node.right);
}
}
}
return ans;
}
public boolean isLeafNode(TreeNode node) {
return node.left == null && node.right == null;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/sum-of-left-leaves/solution/zuo-xie-zi-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
合并二叉树(simple难度)
https://leetcode-cn.com/problems/merge-two-binary-trees/
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null) {
return t2;
}
if (t2 == null) {
return t1;
}
TreeNode merged = new TreeNode(t1.val + t2.val);
merged.left = mergeTrees(t1.left, t2.left);
merged.right = mergeTrees(t1.right, t2.right);
return merged;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/merge-two-binary-trees/solution/he-bing-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null) {
return t2;
}
if (t2 == null) {
return t1;
}
TreeNode merged = new TreeNode(t1.val + t2.val);
Queue<TreeNode> queue = new LinkedList<TreeNode>();
Queue<TreeNode> queue1 = new LinkedList<TreeNode>();
Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
queue.offer(merged);
queue1.offer(t1);
queue2.offer(t2);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
TreeNode node = queue.poll(), node1 = queue1.poll(), node2 = queue2.poll();
TreeNode left1 = node1.left, left2 = node2.left, right1 = node1.right, right2 = node2.right;
if (left1 != null || left2 != null) {
if (left1 != null && left2 != null) {
TreeNode left = new TreeNode(left1.val + left2.val);
node.left = left;
queue.offer(left);
queue1.offer(left1);
queue2.offer(left2);
} else if (left1 != null) {
node.left = left1;
} else if (left2 != null) {
node.left = left2;
}
}
if (right1 != null || right2 != null) {
if (right1 != null && right2 != null) {
TreeNode right = new TreeNode(right1.val + right2.val);
node.right = right;
queue.offer(right);
queue1.offer(right1);
queue2.offer(right2);
} else if (right1 != null) {
node.right = right1;
} else {
node.right = right2;
}
}
}
return merged;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/merge-two-binary-trees/solution/he-bing-er-cha-shu-by-leetcode-solution/
来源:力扣(LeetCode)
二叉搜索树中的搜索(simple难度)
https://leetcode-cn.com/problems/search-in-a-binary-search-tree/
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || val == root.val) return root;
return val < root.val ? searchBST(root.left, val) : searchBST(root.right, val);
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/search-in-a-binary-search-tree/solution/er-cha-sou-suo-shu-zhong-de-sou-suo-by-leetcode/
来源:力扣(LeetCode)
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while (root != null && val != root.val)
root = val < root.val ? root.left : root.right;
return root;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/search-in-a-binary-search-tree/solution/er-cha-sou-suo-shu-zhong-de-sou-suo-by-leetcode/
来源:力扣(LeetCode)
二叉搜索树的最小绝对差(medium难度)
https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/
与本题相同题目:
class Solution {
int pre;
int ans;
public int getMinimumDifference(TreeNode root) {
ans = Integer.MAX_VALUE;
pre = -1;
dfs(root);
return ans;
}
public void dfs(TreeNode root) {
if (root == null) {
return;
}
dfs(root.left);
if (pre == -1) {
pre = root.val;
} else {
ans = Math.min(ans, root.val - pre);
pre = root.val;
}
dfs(root.right);
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/solution/er-cha-sou-suo-shu-jie-dian-zui-xiao-ju-8u87w/
来源:力扣(LeetCode)
二叉搜索树中的众数(simple难度)
https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/
List<Integer> mList = new ArrayList<>();
int curent = 0;//表示当前节点的值
int count = 0;//表示当前节点的数量
int maxCount = 0;//最大的重复数量
public int[] findMode(TreeNode root) {
inOrderTraversal(root);
int[] res = new int[mList.size()];
//把集合list转化为数组
for (int i = 0; i < mList.size(); i++) {
res[i] = mList.get(i);
}
return res;
}
//递归方式
public void inOrderTraversal(TreeNode node) {
//终止条件判断
if (node == null)
return;
//遍历左子树
inOrderTraversal(node.left);
//下面是对当前节点的一些逻辑操作
int nodeValue = node.val;
if (nodeValue == curent) {
//如果节点值等于curent,count就加1
count++;
} else {
//否则,就表示遇到了一个新的值,curent和count都要
//重新赋值
curent = nodeValue;
count = 1;
}
if (count == maxCount) {
//如果count == maxCount,就把当前节点加入到集合中
mList.add(nodeValue);
} else if (count > maxCount) {
//否则,当前节点的值重复量是最多的,直接把list清空,然后
//把当前节点的值加入到集合中
mList.clear();
mList.add(nodeValue);
maxCount = count;
}
//遍历右子树
inOrderTraversal(node.right);
}
作者:sdwwld
链接:https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/solution/er-cha-shu-zhong-xu-bian-li-de-liang-chong-fang-sh/
来源:力扣(LeetCode)
二叉树的最近公共祖先(medium难度)
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
与本题相同题目:
本题方法和代码来源:
作者:jyd
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/
来源:力扣(LeetCode)
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; // 1.
if(left == null) return right; // 3.
if(right == null) return left; // 4.
return root; // 2. if(left != null and right != null)
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/
来源:力扣(LeetCode)
二叉搜索树的最近公共祖先(simple难度)
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/
与本题相同的题目:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode ancestor = root;
while (true) {
if (p.val < ancestor.val && q.val < ancestor.val) {
ancestor = ancestor.left;
} else if (p.val > ancestor.val && q.val > ancestor.val) {
ancestor = ancestor.right;
} else {
break;
}
}
return ancestor;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/solution/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-26/
来源:力扣(LeetCode)
我的代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == p || root == q ){
return root;
}
if((p.val < root.val && q.val > root.val)||(q.val < root.val && p.val > root.val)){
return root;
}else if(p.val < root.val && q.val < root.val){
return lowestCommonAncestor(root.left,p,q);
}else{
return lowestCommonAncestor(root.right,p,q);
}
}
}
作者:HIT_whc
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/solution/javali-yong-er-cha-sou-suo-shu-xing-zhi-6mgpg/
来源:力扣(LeetCode)
二叉搜索树中的插入操作(medium难度)
https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/
本题方法和代码来源:
作者:sweetiee
链接:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/solution/2-de-cha-ru-by-sweetiee/
来源:力扣(LeetCode)
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) {
return new TreeNode(val);
}
if (root.val < val) {
root.right = insertIntoBST(root.right, val);
} else {
root.left = insertIntoBST(root.left, val);
}
return root;
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/solution/2-de-cha-ru-by-sweetiee/
来源:力扣(LeetCode)
我的代码:
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null){
return new TreeNode(val);
}
if(root.val < val){
root.right = insertIntoBST(root.right,val);
}else{
root.left = insertIntoBST(root.left,val);
}
return root;
}
}
作者:HIT_whc
链接:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/solution/javaji-jian-di-gui-suan-fa-shi-jian-ji-b-97jy/
来源:力扣(LeetCode)
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
TreeNode node = new TreeNode(val);
if (root == null) {
return node;
}
TreeNode cur = root;
while (true) {
if (cur.val > val) {
if (cur.left == null) {
cur.left = node;
break;
}
cur = cur.left;
} else {
if (cur.right == null) {
cur.right = node;
break;
}
cur = cur.right;
}
}
return root;
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/solution/2-de-cha-ru-by-sweetiee/
来源:力扣(LeetCode)
删除二叉搜索树中的节点(medium难度)
https://leetcode-cn.com/problems/delete-node-in-a-bst/
本题方法和代码来源:
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/yong-qian-qu-huo-zhe-hou-ji-jie-dian-zi-shu-dai-ti/
来源:力扣(LeetCode)
方法一:用前驱结点(左子树中最大结点)代替被删除结点
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val) {
root.left = deleteNode(root.left, key);
return root;
}
if (key > root.val) {
root.right = deleteNode(root.right, key);
return root;
}
assert key == root.val;
if (root.left == null) {
TreeNode right = root.right;
root.right = null;
return right;
}
if (root.right == null) {
TreeNode left = root.left;
root.left = null;
return left;
}
TreeNode predecessor = maximum(root.left);
TreeNode predecessorCopy = new TreeNode(predecessor.val);
predecessorCopy.left = removeMax(root.left);
predecessorCopy.right = root.right;
root.left = null;
root.right = null;
return predecessorCopy;
}
private TreeNode removeMax(TreeNode node) {
if (node.right == null) {
TreeNode left = node.left;
node.left = null;
return left;
}
node.right = removeMax(node.right);
return node;
}
private TreeNode maximum(TreeNode node) {
if (node.right == null) {
return node;
}
return maximum(node.right);
}
}
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/yong-qian-qu-huo-zhe-hou-ji-jie-dian-zi-shu-dai-ti/
来源:力扣(LeetCode)
方法二:用后继结点(右子树中最小结点)代替被删除结点
public class Solution {
private TreeNode minNode(TreeNode node) {
while (node.left != null) {
node = node.left;
}
return node;
}
/**
* 删除一个二分搜索树中最小的节点,把新的二分搜索树的根返回回去
* 使用递归,要特别注意,定义的递归函数,返回的是,删除了最小值节点以后的新的二分搜索树的根
*
* @param node
* @return
*/
private TreeNode removeMin(TreeNode node) {
if (node.left == null) {
// 就是那个我们要删除的节点
TreeNode rightNode = node.right;
node.right = null;
return rightNode;
}
node.left = removeMin(node.left);
return node;
}
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (root.val < key) {
root.right = deleteNode(root.right, key);
return root;
} else if (root.val > key) {
root.left = deleteNode(root.left, key);
return root;
} else {
// 如果待删除的节点左孩子为空
if (root.left == null) {
TreeNode rightNode = root.right;
root.right = null;
return rightNode;
}
// 如果待删除的节点只有右孩子
if (root.right == null) {
TreeNode leftNode = root.left;
root.left = null;
return leftNode;
}
// 从它的右子树中拿到最小的
TreeNode successor = new TreeNode(minNode(root.right).val);
successor.left = root.left;
successor.right = removeMin(root.right);
root.left = null;
root.right = null;
return successor;
}
}
}
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/yong-qian-qu-huo-zhe-hou-ji-jie-dian-zi-shu-dai-ti/
来源:力扣(LeetCode)
修剪二叉搜索树(medium难度)
https://leetcode-cn.com/problems/trim-a-binary-search-tree/
本题方法和代码来源:
作者:rang-dan-dan-fei
链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree/solution/san-chong-jie-fa-di-gui-die-dai-dfs-by-r-ikyk/
来源:力扣(LeetCode)
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) return root;
// 区间[low,high]位于root的左子树,则修剪后的二叉搜索树位于root的左子树
if (root.val > high) {
return trimBST(root.left, low, high);
}
// 区间[low,high]位于root的右子树,则修剪后的二叉搜索树位于root的右子树
if (root.val < low) {
return trimBST(root.right, low, high);
}
// 区间[low,high]包含root节点,则分别对root的左子树和右子树进行修剪,修剪完成后分别赋给root的左、右节点
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
作者:rang-dan-dan-fei
链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree/solution/san-chong-jie-fa-di-gui-die-dai-dfs-by-r-ikyk/
来源:力扣(LeetCode)
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) return root;
// 找到修剪后的二叉搜索树的头节点root,则头节点root位于`[low,high]`区间内
while((root != null)&&(root.val > high || root.val < low)) {
root = root.val > high ? root.left : root.right;
}
// 循环迭代处理root的左子树,将小于low的节点排除掉,剩下节点都在`[low,high]`区间内
TreeNode curr = root;
while (curr != null) {
while (curr.left != null && curr.left.val < low) {
curr.left = curr.left.right;
}
curr = curr.left;
}
// 循环迭代处理root的右子树,将大于high的节点排除掉,剩下节点都在`[low,high]`区间内
curr = root;
while (curr != null) {
while (curr.right != null && curr.right.val > high) {
curr.right = curr.right.left;
}
curr = curr.right;
}
return root;
}
}
作者:rang-dan-dan-fei
链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree/solution/san-chong-jie-fa-di-gui-die-dai-dfs-by-r-ikyk/
来源:力扣(LeetCode)
将有序数组转换为二叉搜索树(simple难度)
https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return dfs(nums, 0, nums.length - 1);
}
private TreeNode dfs(int[] nums, int lo, int hi) {
if (lo > hi) {
return null;
}
// 以升序数组的中间元素作为根节点 root。
int mid = lo + (hi - lo) / 2;
TreeNode root = new TreeNode(nums[mid]);
// 递归的构建 root 的左子树与右子树。
root.left = dfs(nums, lo, mid - 1);
root.right = dfs(nums, mid + 1, hi);
return root;
}
}
作者:sweetiee
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/solution/jian-dan-di-gui-bi-xu-miao-dong-by-sweetiee/
来源:力扣(LeetCode)
把二叉搜索树转换为累加树(medium难度)
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;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/solution/ba-er-cha-sou-suo-shu-zhuan-huan-wei-lei-jia-sh-14/
来源:力扣(LeetCode)