Эта статья была впервые опубликована в моем личном блоге:племя хвост хвост
0. Несколько концепций
Полное бинарное дерево: если высота бинарного дерева равна h, за исключением h-го слоя, количество узлов в других (1~h-1) слоях достигло максимального числа, а узлы h-го слоя й слой постоянно концентрируется на крайнем левом. Думать о чем-то? На самом деле полное бинарное дерево и куча более тесно связаны~~~
Полное бинарное дерево: все узлы на каждом слое имеют двух дочерних элементов, кроме последнего слоя, а последний слой является конечным узлом.
Дерево Хаффмана: учитывая n весов в качестве листовых узлов n, постройте двоичное дерево. Если длина взвешенного пути достигает минимума, такое двоичное дерево называется оптимальным двоичным деревом, также известным как дерево Хаффмана. ).
Двоичное дерево сортировки: также известное как двоичное дерево поиска, также известное как двоичное дерево поиска. Бинарное отсортированное дерево — это либо пустое дерево, либо бинарное дерево со следующими свойствами:
- Если левое поддерево не пусто, значение всех узлов левого поддерева меньше значения его корневого узла;
- Если правое поддерево не пусто, значение всех узлов в правом поддереве больше или равно значению его корневого узла;
- Левое и правое поддеревья также являются деревьями с бинарной сортировкой соответственно;
- нет узлов с одинаковыми ключами
Временная сложность бинарного поиска составляет O (log (n)), а временная сложность в наихудшем случае - O (n) (эквивалентно последовательному поиску).
Сбалансированное двоичное дерево: также известное как дерево AVL. Сбалансированное бинарное дерево является эволюционной версией бинарного дерева поиска, так называемое сбалансированное бинарное дерево означает, что абсолютное значение разницы высот между левым и правым поддеревьями не превышает 1.
Красно-черное дерево: Красно-черное дерево — это дерево, в котором каждый узел окрашен, а цвет узла либо красный, либо черный.Красно-черное дерево — это дерево поиска. Важным свойством красно-черных деревьев является то, что самый длинный путь от корневого узла до конечного узла не более чем в два раза превышает длину кратчайшего пути. Для красно-черного дерева вставка, удаление и поиск выполняются за O(log N).
1. Найдите количество узлов в бинарном дереве
Рекурсивное решение: (1) Если бинарное дерево пусто, количество узлов равно 0. (2) Если оно не пусто, количество узлов бинарного дерева = количество узлов левого поддерева + количество узлов правого поддерева + 1 Справочный код выглядит следующим образом:
public static int getNodeNumRec(TreeNode root) {
if (root == null) {
return 0;
}
return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1;
}
2. Найдите максимальный уровень (максимальную глубину) бинарного дерева
Меч относится к предложению:глубина бинарного дереваРекурсивное решение: (1) Если бинарное дерево пусто, глубина бинарного дерева равна 0 (2) Если бинарное дерево не пусто, то глубина бинарного дерева = max (глубина левого поддерева, глубина правого поддерева) + 1 Справочный код выглядит следующим образом:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root == null)
return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right))+1;
}
}
2.1 Минимальная глубина бинарного дерева
LeetCode:Minimum Depth of Binary TreeДля заданного бинарного дерева найти его минимальную глубину. Минимальная глубина — это количество узлов на кратчайшем пути от корневого узла до ближайшего конечного узла.
class Solution {
public int minDepth(TreeNode root) {
if(root == null)
return 0;
int left = minDepth(root.left);
int right = minDepth(root.right);
return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1;
}
}
3. Обход предварительного заказа/обход предварительного заказа
LeetCode:Binary Tree Preorder TraversalУчитывая бинарное дерево, верните предварительный обход его значений узлов.
根 - 左 - 右
рекурсия
ArrayList<Integer> preOrderReverse(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
preOrder(root, result);
return result;
}
void preOrder(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
result.add(root.val);
preOrder(root.left, result);
preOrder(root.right, result);
}
нерекурсивный
Закон первый:
import java.util.Stack;
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
res.add(node.val);
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
return res;
}
}
Закон второй:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
if(cur!=null){
res.add(cur.val);
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
cur = cur.right;
}
}
return res;
}
}
4. Обход по порядку
LeetCode:Binary Tree Inorder TraversalУчитывая бинарное дерево, верните упорядоченный обход его значений узла.
左 - 根 - 右
рекурсия
void inOrder(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
preOrder(root.left, result);
result.add(root.val);
preOrder(root.right, result);
}
нерекурсивный
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(!stack.isEmpty() || cur != null){
if(cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
}
return res;
}
}
5. Обход после заказа
Литкод:Binary Tree Postorder TraversalУчитывая бинарное дерево, верните обратный обход его значений узла.
左 - 右 - 根
рекурсия
void inOrder(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
preOrder(root.left, result);
preOrder(root.right, result);
result.add(root.val);
}
нерекурсивный
метод первый:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> ans = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
if (root == null) return ans;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
//采用逆序插入的方式
ans.addFirst(cur.val);
if (cur.left != null) {
stack.push(cur.left);
}
if (cur.right != null) {
stack.push(cur.right);
}
}
return ans;
}
}
Способ второй:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
TreeNode visited = null;
while(!stack.isEmpty() || cur != null){
if(cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.peek();
if(cur.right != null && cur.right != visited){
cur = cur.right;
}else{
res.add(cur.val);
visited = cur;
stack.pop();
cur = null;
}
}
}
return res;
}
}
Способ 3 (рекомендуемый):
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> result = new LinkedList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode p = root;
while(!stack.isEmpty() || p != null) {
if(p != null) {
stack.push(p);
result.addFirst(p.val); // Reverse the process of preorder
p = p.right; // Reverse the process of preorder
} else {
TreeNode node = stack.pop();
p = node.left; // Reverse the process of preorder
}
}
return result;
}
}
6. Иерархический обход
LeetCode:Binary Tree Level Order TraversalМеч относится к предложению:Распечатайте бинарное дерево сверху внизМеч относится к предложению:печатать бинарное дерево в несколько строкУчитывая бинарное дерево, верните обход его значений узла в порядке уровней.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(root == null)
return res;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
TreeNode cur = null;
queue.add(root);
while(!queue.isEmpty()){
ArrayList<Integer> level = new ArrayList<Integer>();
int l = queue.size();
for(int i=0; i<l;i++){
cur = queue.poll();
level.add(cur.val);
if(cur.left != null)
queue.add(cur.left);
if(cur.right != null)
queue.add(cur.right);
}
res.add(level);
}
return res;
}
}
6.1 Иерархический обход снизу вверх
LeetCode:Binary Tree Level Order Traversal IIУчитывая бинарное дерево, верните восходящий обход его значений узла в порядке уровней.
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
Queue<TreeNode> queue = new LinkedList<>();
if(root == null)
return res;
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List<Integer> temp = new LinkedList<>();
for(int i=0; i<count; 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;
}
}
6.2 Печать бинарного дерева в зигзагообразном порядке
Меч относится к предложению:Вывести бинарное дерево в зигзагообразном порядкеПожалуйста, реализуйте функцию печати бинарного дерева в виде зигзага, то есть первая строка печатается слева направо, второй слой печатается справа налево, третья строка печатается слева -вправо, а остальные строки печатаются слева направо и так далее.
Настройте два стека, s2 хранит слои с нечетными номерами, а s1 хранит слои с четными номерами. Обходя узел s2, соедините s1 в порядке левого поддерева и правого поддерева, Обходя узел s1, соедините s2 в порядке правого поддерева и левого поддерева.
import java.util.ArrayList;
import java.util.Stack;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
Stack<TreeNode> s1 = new Stack<TreeNode>();
Stack<TreeNode> s2 = new Stack<TreeNode>();
int flag = 1;
if(pRoot == null)
return res;
s2.push(pRoot);
ArrayList<Integer> temp = new ArrayList<Integer>();
while(!s1.isEmpty() || !s2.isEmpty()){
if(flag % 2 != 0){
while(!s2.isEmpty()){
TreeNode node = s2.pop();
temp.add(node.val);
if(node.left != null){
s1.push(node.left);
}
if(node.right != null){
s1.push(node.right);
}
}
}
if(flag % 2 == 0){
while(!s1.isEmpty()){
TreeNode node = s1.pop();
temp.add(node.val);
if(node.right != null){
s2.push(node.right);
}
if(node.left != null){
s2.push(node.left);
}
}
}
res.add(new ArrayList<Integer>(temp));
temp.clear();
flag ++;
}
return res;
}
}
7. Найдите количество узлов в K-м слое бинарного дерева.
void get_k_level_number(TreeNode root, int k){
if(root == null || k <=0){
return 0;
}
if(root != null && k == 1){
return 1;
}
return get_k_level_number(root.left, k-1) + get_k_level_number(root.right, k-1);
}
8. Найдите количество листовых узлов в K-м слое бинарного дерева.
void get_k_level_leaf_number(TreeNode root, int k){
if(root == null || k <=0){
return 0;
}
if(root != null && k == 1){
if(root.left == null && root.right == null)
return 1;
else
return 0;
}
return get_k_level_number(root.left, k-1) + get_k_level_number(root.right, k-1);
}
9. Определите, имеют ли два бинарных дерева одинаковую структуру
LeetCode:Same TreeИмея два бинарных дерева, напишите функцию, проверяющую, совпадают ли они.
Рекурсивное решение: (1) Если оба бинарных дерева пусты, вернуть true (2) Если одно из двух бинарных деревьев пусто, а другое не пусто, вернуть false (3) Если оба двоичных дерева не пусты, если соответствующие левое поддерево и правое поддерево изоморфны, вернуть true, в противном случае вернуть false
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 isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
return false;
}
}
10. Определите, является ли бинарное дерево сбалансированным бинарным деревом
LeetCode:Balanced Binary TreeУчитывая бинарное дерево, определите, является ли оно высоко сбалансированным. Для этой задачи бинарное дерево со сбалансированной высотой определяется как: Бинарное дерево, в котором глубины двух поддеревьев каждого узла не отличаются более чем на 1.
Рекурсивное решение: (1) Если бинарное дерево пусто, вернуть true (2) Если двоичное дерево не пусто, если разница в высоте между левым поддеревом и правым поддеревом не больше 1, а левое поддерево и правое поддерево оба являются деревьями AVL, вернуть true, в противном случае вернуть false
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null)
return true;
return Math.abs(maxHigh(root.left) - maxHigh(root.right)) <= 1
&& isBalanced(root.left) && isBalanced(root.right);
}
public int maxHigh(TreeNode root){
if(root == null)
return 0;
return Math.max(maxHigh(root.left), maxHigh(root.right))+1;
}
}
11. Найдите зеркальное отражение бинарного дерева
Меч относится к предложению:зеркальное отображение бинарного дереваLeetCode:Invert Binary TreeИнвертировать бинарное дерево
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null)
return root;
TreeNode node = root.left;
root.left = invertTree(root.right);
root.right = invertTree(node);
return root;
}
}
11.1 Симметричные бинарные деревья
Меч относится к предложению:Симметричное бинарное деревоLeetCode:Symmetric TreeИмея бинарное дерево, проверьте, является ли оно зеркально симметричным.
class Solution {
public boolean isSymmetric(TreeNode root) {
return root == null || isSymmetricHelper(root.left, root.right);
}
public boolean isSymmetricHelper(TreeNode left, TreeNode right){
if(left == null && right == null)
return true;
if(left == null || right == null)
return false;
if(left.val != right.val)
return false;
return isSymmetricHelper(left.left, right.right) && isSymmetricHelper(left.right, right.left);
}
}
12. Найдите наименьшего общего предка двух узлов в бинарном дереве.
Рекурсивное решение: (1) Если два узла находятся в левом поддереве и правом поддереве корневого узла, вернуть корневой узел (2) Если оба узла находятся в левом поддереве, рекурсивно обработать левое поддерево; если оба узла находятся в правом поддереве, рекурсивно обработать правое поддерево.LeetCode:Lowest Common Ancestor of a Binary TreeДля заданного бинарного дерева найдите наименьшего общего предка (LCA) двух заданных узлов в дереве.
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 root;
return left == null ? right : left;
}
}
12.1 Поиск ближайшего общего предка бинарного дерева поиска
Обратите внимание на свойства бинарных деревьев поиска:LeetCode:Lowest Common Ancestor of a Binary Search TreeУчитывая бинарное дерево поиска, найдите ближайшего общего предка двух заданных узлов в дереве. Определение ближайшего общего предка в энциклопедии Baidu звучит так: «Для двух узлов p и q корневого дерева T ближайший общий предок представлен как узел x, который удовлетворяет тому, что x является предком p и q, а глубина x как можно больше. (Узел также может быть своим собственным предком)».
左子树
< 根节点
< 右子树
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val > p.val && root.val > q.val){
return lowestCommonAncestor(root.left, p, q);
}
else if(root.val < p.val && root.val < q.val){
return lowestCommonAncestor(root.right, p, q);
}
else{
return root;
}
}
}
13. Найдите диаметр бинарного дерева
Рекурсивное решение: для каждого узла его самый длинный путь равен самому длинному пути левого поддерева + самому длинному пути правого поддерева.LeetCode:Diameter of Binary TreeУчитывая бинарное дерево, вам нужно вычислить длину его диаметра. Диаметр бинарного дерева — это максимальная длина пути любых двух узлов. Этот путь может проходить через корневой узел.
class Solution {
private int path = 0;
public int diameterOfBinaryTree(TreeNode root) {
diamHelper(root);
return path;
}
private int diamHelper(TreeNode root){
if(root == null)
return 0;
int left = diamHelper(root.left);
int right = diamHelper(root.right);
path = Math.max(path, left + right);
return Math.max(left, right) + 1;
}
}
14. Восстановите бинарное дерево из последовательности обхода в прямом порядке и последовательности обхода в неупорядоченном порядке.
Меч относится к предложению:Восстановить бинарное деревоLeetCode:Construct Binary Tree from Preorder and Inorder TraversalПостройте бинарное дерево на основе обхода в прямом и неупорядоченном порядке.
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 || inorder.length == 0)
return null;
return buildTreeHelper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
public TreeNode buildTreeHelper(int[] preorder, int pre_start, int pre_end,
int[] inorder, int in_start, int in_end){
if(pre_start > pre_end || in_start > in_end)
return null;
TreeNode root = new TreeNode(preorder[pre_start]);
for(int i = in_start; i <= in_end; i++){
if(inorder[i] == preorder[pre_start]){
// 左子树的长度:i-is
root.left = buildTreeHelper(preorder, pre_start + 1, pre_start + i - in_start, inorder, in_start, i - 1);
root.right = buildTreeHelper(preorder, pre_start + i - in_start + 1, pre_end, inorder, i + 1, in_end);
}
}
return root;
}
}
14.1 Построение бинарных деревьев из последовательностей обхода в порядке и обратном порядке
Этот вопрос представляет собой процедуру с «Построение двоичного дерева из последовательности обхода в прямом и неупорядоченном порядке». Единственное отличие состоит в том, что последний узел последовательности пост-порядка является корневым узлом, поэтому мы должны начать с последнего узла последовательности пост-порядка, а затем перейти к последовательности порядка, чтобы найти этот узел. Левая часть этого узла принадлежит левой части поддерева корневого узла, а правая часть принадлежит правой части поддерева корневого узла. Затем в соответствии с количеством левых и правых узлов поддерева найдите их соответствующую пост-последовательность в пост-последовательности. Если число узлов в левом поддереве равно 5, то первые пять узлов в последовательности после последовательности являются узлами левого поддерева, а последующие узлы, кроме последнего узла, являются узлами правого поддерева.LeetCode:Construct Binary Tree from Inorder and Postorder TraversalПостроить бинарное дерево на основе обхода дерева в упорядоченном и обратном порядке.
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder.length == 0 || postorder.length == 0)
return null;
return buildTreeHelper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}
public TreeNode buildTreeHelper(int[] inorder, int in_start, int in_end,
int[] postorder, int post_start, int post_end){
if(in_start > in_end || post_start > post_end)
return null;
TreeNode root = new TreeNode(postorder[post_end]);
for(int i = in_start; i <= in_end; i++){
if(inorder[i] == postorder[post_end]){
root.left = buildTreeHelper(inorder, in_start, i - 1, postorder, post_start, post_start + i - in_start - 1);
root.right = buildTreeHelper(inorder, i + 1, in_end, postorder, post_start + i - in_start, post_end - 1);
}
}
return root;
}
}
Подсказка: уникальное двоичное дерево не может быть построено из обхода в прямом и обратном порядке.
15. Определите, является ли бинарное дерево полным бинарным деревом
Полное бинарное дерево означает, что левая сторона последнего слоя заполнена, правая сторона может быть медленной, но не полной, а затем остальные слои заполнены.Согласно этой функции используется обход слоя. Если мы в настоящее время переходим к узлу NULL, если в будущем будут узлы, отличные от NULL, это означает, что это неполное двоичное дерево.
class Solution {
public boolean _CheckCompleteTree(TreeNode root) {
Queue<TreeNode> queue = LinkedList<>();
if(root == null)
return true;
queue.add(root);
while(!queue.isEmpty()){
TreeNode node = queue.pop();
if(node != null){
if(flag == true)
return false;
queue.add(node.left);
queue.add(node.right);
}else{
flag = true;
}
}
return true;
}
}
16. Подструктура дерева
Меч относится к предложению:подструктура дереваВведите два бинарных дерева A и B и определите, является ли B подструктурой A.
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1 == null || root2 == null){
return false;
}
return IsSubtree(root1, root2) ||
HasSubtree(root1.left, root2) ||
HasSubtree(root1.right, root2);
}
public boolean IsSubtree(TreeNode root1, TreeNode root2){
//要先判断roo2, 不然{8,8,7,9,2,#,#,#,#,4,7},{8,9,2}这个测试用例通不过。
if(root2 == null)
return true;
if(root1 == null)
return false;
if(root1.val == root2.val){
return IsSubtree(root1.left, root2.left) &&
IsSubtree(root1.right, root2.right);
}else
return false;
}
}
17. Путь в бинарном дереве, который суммируется со значением
Меч относится к предложению:Путь в бинарном дереве, который суммируется со значениемВведите бинарное дерево и целое число, выведите все пути в бинарном дереве, сумма значений узлов которых является входным целым числом. Путь определяется как путь от корневого узла дерева до узлов, пройденных конечными узлами.
public class Solution {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
ArrayList<Integer> temp = new ArrayList<Integer>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
if(root == null)
return res;
target -= root.val;
temp.add(root.val);
if(target == 0 && root.left == null && root.right == null)
res.add(new ArrayList<Integer>(temp));
else{
FindPath(root.left, target);
FindPath(root.right, target);
}
temp.remove(temp.size()-1);
return res;
}
}
18. Следующий узел бинарного дерева
Меч относится к предложению:следующий узел в бинарном деревеИмея бинарное дерево и узел в нем, найдите следующий узел в порядке обхода и вернитесь. Обратите внимание, что узлы в дереве содержат не только левые и правые дочерние узлы, но и указатели на родительские узлы.
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
if(pNode == null){
return null;
}
if(pNode.right != null){
TreeLinkNode node = pNode.right;
while(node.left != null){
node = node.left;
}
return node;
}
while(pNode.next != null){
TreeLinkNode root = pNode.next;
if(pNode == root.left)
return root;
pNode = root;
}
return null;
}
}
19. Сериализация двоичного дерева
Меч относится к предложению:сериализовать бинарное деревоLeetCode:Serialize and Deserialize Binary TreeПожалуйста, реализуйте две функции для сериализации и десериализации бинарных деревьев соответственно.
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root == null)
return "#,";
StringBuffer res = new StringBuffer(root.val + ",");
res.append(serialize(root.left));
res.append(serialize(root.right));
return res.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String [] d = data.split(",");
Queue<String> queue = new LinkedList<>();
for(int i = 0; i < d.length; i++){
queue.offer(d[i]);
}
return pre(queue);
}
public TreeNode pre(Queue<String> queue){
String val = queue.poll();
if(val.equals("#"))
return null;
TreeNode node = new TreeNode(Integer.parseInt(val));
node.left = pre(queue);
node.right = pre(queue);
return node;
}
}
20. k-й узел бинарного дерева поиска
Поскольку последовательность обхода бинарного дерева поиска для вывода сортируется, поэтому мы проходим, чтобы найти k-й узел, являющийся предметом запроса в соответствии с последовательностью узлов.Меч относится к предложению:k-й узел бинарного дерева поискаДля заданного бинарного дерева поиска найти в нем k-й наименьший узел. Например, в (5, 3, 7, 2, 4, 6, 8) значение третьего наименьшего узла в порядке нумерации узлов равно 4.
class Solution {
public int kthSmallest(TreeNode root, int k) {
if(root == null)
return Integer.MIN_VALUE;
Stack<TreeNode> stack = new Stack<>();
int count = 0;
TreeNode p = root;
while(p != null || !stack.isEmpty()){
if(p != null){
stack.push(p);
p = p.left;
}else{
TreeNode node = stack.pop();
count ++;
if(count == k)
return node.val;
p = node.right;
}
}
return Integer.MIN_VALUE;
}
}