二叉树面试题解析
判断相同的树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
// 不相同情况:
// 一个根为空 一个根不为空
if (p == null && q != null || p != null && q == null) {
return false;
}
// 走到这说明 两个根都为空 或者 都不为空
// 如果都为空返回true,都不为空判断值
if (p == null && q == null) {
return true;
}
if (p.val != q.val) {
return false;
}
// 走到这说明根相同 接下来判断左右子树是否相同
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
}
另一颗树的子树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
// 不相同情况:
// 一个根为空 一个根不为空
if (p == null && q != null || p != null && q == null) {
return false;
}
// 走到这说明 两个根都为空 或者 都不为空
if (p == null && q == null) {
return true;
}
if (p.val != q.val) {
return false;
}
// 走到这说明根相同 接下来判断左右子树是否相同
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) {
return false;
}
// 判断根
if (isSameTree(root,subRoot)) {
return true;
}
// 判断左子树
if(isSubtree(root.left,subRoot)) {
return true;
}
// 判断右子树
if(isSubtree(root.right,subRoot)) {
return true;
}
return false;
}
}
翻转二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
if (root.left == null && root.right == null) {
return root;
}
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = maxDepth(root.left);
int rightHeight = maxDepth(root.right);
return leftHeight > rightHeight
? leftHeight+1 : rightHeight+1;
}
}
会遍历树中所有的节点,时间复杂度为O(N)
判断平衡二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
// 如何判断是否是平衡二叉树
// 当前根节点左右子树高度差<=1, 左子树平衡 && 右子树平衡
if (root == null) {
return true;
}
int leftTH = maxDepth(root.left);
int rightTH = maxDepth(root.right);
return Math.abs(leftTH - rightTH) <= 1
&& isBalanced(root.left) && isBalanced(root.right);
}
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = maxDepth(root.left);
int rightHeight = maxDepth(root.right);
return leftHeight > rightHeight
? leftHeight+1 : rightHeight+1;
}
}
每一个节点都会去计算高度,n(节点个数) × n(计算一次高度的时间复杂度) = O(n^2)
能否以O(N) 时间复杂度解题 ?
可以, 在计算高度的同时 判断是否平衡
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = maxDepth(root.left);
if (leftHeight == -1) {
return -1;
}
int rightHeight = maxDepth(root.right);
if (leftHeight >= 0 && rightHeight >= 0 &&
Math.abs(leftHeight-rightHeight) <= 1) {
return Math.max(leftHeight,rightHeight)+1;
}else {
return -1;
}
}
public boolean isBalanced(TreeNode root) {
// 计算高度的同时判断是否平衡
if (root == null) {
return true;
}
return maxDepth(root) != -1;
}
}
判断对称二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
// 一个为空 一个不为空 ———— 不对称
if (leftTree == null && rightTree != null) {
return false;
}
if (leftTree != null && rightTree == null) {
return false;
}
if (leftTree == null && rightTree == null) {
return true;
}
if (leftTree.val != rightTree.val) {
return false;
}
// 走到这说明根对称, 然后接下来判断
// 左子树的左——右子树的右 && 左子树的右——右子树的左 是否对称
return isSymmetricChild(leftTree.left,rightTree.right)
&& isSymmetricChild(leftTree.right,rightTree.left);
}
}
前序遍历创建二叉树
import java.util.Scanner;
class TreeNode {
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val) {
this.val = val;
}
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static int i;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) { // 注意 while 处理多个 case
String str = in.nextLine();
// 根据输入的前序遍历创建树
TreeNode root = createTree(str);
// 中序遍历
inOrder(root);
}
}
public static TreeNode createTree(String str) {
TreeNode root = null;
if (str.charAt(i) != '#') {
root = new TreeNode(str.charAt(i));
i++;
root.left = createTree(str);
root.right = createTree(str);
}else {
i++;
}
return root;
}
public static void inOrder(TreeNode root) {
// 左根右
if (root == null) {
return;
}
inOrder(root.left);
System.out.print(root.val+" ");
inOrder(root.right);
}
}
二叉树的层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ret = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if (root == null) {
return ret;
}
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> array = new ArrayList<>();
int size = queue.size();
while (size != 0) {
TreeNode cur = queue.poll();
array.add(cur.val);
size--;
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null) {
queue.offer(cur.right);
}
}
ret.add(array);
}
return ret;
}
}
二叉树的最近公共祖先
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (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;
}else if(left != null) {
return left;
}else {
return right;
}
}
}
这道题还有一个很有意思的题解
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
// 得到root -> node路径上所有节点
public boolean getPathNode(TreeNode root,TreeNode node,Stack<TreeNode> stack) {
if (root == null || node == null) {
return false;
}
stack.push(root);
if (root == node) {
return true;
}
boolean leftFlag = getPathNode(root.left,node,stack);
if (leftFlag == true) {
return true;
}
boolean rightFlag = getPathNode(root.right,node,stack);
if (rightFlag == true) {
return true;
}
stack.pop();
return false;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
Stack<TreeNode> stackP = new Stack<>();
Stack<TreeNode> stackQ = new Stack<>();
getPathNode(root,p,stackP);
getPathNode(root,q,stackQ);
int sizeP = stackP.size();
int sizeQ = stackQ.size();
if (sizeP > sizeQ) {
int gap = sizeP - sizeQ;
while (gap != 0) {
stackP.pop();
gap--;
}
}else {
int gap = sizeQ - sizeP;
while (gap != 0) {
stackQ.pop();
gap--;
}
}
while (!stackP.isEmpty() && !stackQ.isEmpty()) {
TreeNode nodeP = stackP.pop();
TreeNode nodeQ = stackQ.pop();
if (nodeP == nodeQ) {
return nodeP;
}
}
return null;
}
}
从前序与中序遍历序列构造二叉树
解这道题的重点:
左子树 = [0, rootindex - 1]
右子树 = [rootindex+1, inend]
力扣通过代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int preIndex ;
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
private TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend) {
if (inbegin > inend) {
return null;
}
TreeNode root = new TreeNode(preorder[this.preIndex]);
int rootIndex = findIndexRoot(inorder,0,inorder.length,root.val);
this.preIndex++;
root.left = buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
root.right = buildTreeChild(preorder,inorder,rootIndex+1,inend);
return root;
}
private int findIndexRoot(int[] inorder,int inbegin, int inend,int key) {
for (int i = inbegin;i < inend;i++) {
if (inorder[i] == key) {
return i;
}
}
return -1;
}
}
测试代码:
public class SolutionCreateTree {
static class TreeNode {
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val) {
this.val = val;
}
}
public int preIndex ;
public TreeNode buildTree(char[] preorder, char[] inorder) {
return buildTreeChild(preorder,inorder,0,inorder.length);
}
private TreeNode buildTreeChild(char[] preorder,char[] inorder,int inbegin,int inend) {
if (inbegin > inend) {
return null;
}
TreeNode root = new TreeNode(preorder[this.preIndex]);
int rootIndex = findIndexRoot(inorder,0,inorder.length,root.val);
this.preIndex++;
root.left = buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
root.right = buildTreeChild(preorder,inorder,rootIndex+1,inend);
return root;
}
private int findIndexRoot(char[] inorder,int inbegin, int inend,int key) {
for (int i = inbegin;i < inend;i++) {
if (inorder[i] == key) {
return i;
}
}
return -1;
}
}
public class Test {
public static void main(String[] args) {
SolutionCreateTree solutionCreateTree = new SolutionCreateTree();
char[] preorder = {'E','F','H','I','G','J','K'};
char[] inorder = {'H','F','I','E','J','K','G'};
SolutionCreateTree.TreeNode root = solutionCreateTree.buildTree(preorder,inorder);
}
}
图解:
https://github.com/znxcmakhsd/DS/blob/main/12-29
从中序与后序遍历序列构造二叉树
/**
* 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 {
/*static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}*/
public int postIndex;
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.postIndex = postorder.length-1;
return buildTreeChild(inorder,postorder,0,this.postIndex);
}
public TreeNode buildTreeChild(int[] inorder, int[] postorder,int inBegin,int inEnd) {
if (inBegin > inEnd) {
return null;
}
TreeNode root = new TreeNode(postorder[postIndex]);
int rootIndex = findRootIndex(inorder,inBegin,inEnd,root.val);
this.postIndex--;
root.right = buildTreeChild(inorder,postorder,rootIndex+1,inEnd);
root.left = buildTreeChild(inorder,postorder,inBegin,rootIndex-1);
return root;
}
public int findRootIndex(int[] inorder,int inBegin,int inEnd,int key) {
for (int i = inBegin;i <= inEnd;i++) {
if (inorder[i] == key) {
return i;
}
}
return -1;
}
}
根据二叉树创建字符串
力扣通过代码:
/**
* 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 String tree2str(TreeNode root) {
StringBuilder stringBuilder = new StringBuilder();
buildString(root,stringBuilder);
return stringBuilder.toString();
}
public void buildString(TreeNode root,StringBuilder stringBuilder) {
if (root == null) {
return;
}
stringBuilder.append(root.val);
if (root.left != null) {
stringBuilder.append("(");
buildString(root.left,stringBuilder);
stringBuilder.append(")");
}else {
// 两种情况:
// 1. 左右都为空
if (root.right == null) {
return;
}else {
// 2. 左为空 右不为空
stringBuilder.append("()");
}
}
if (root.right != null) {
stringBuilder.append("(");
buildString(root.right,stringBuilder);
stringBuilder.append(")");
}else {
// 右边为空 直接返回
return;
}
}
}
测试代码:
public class Solution {
static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
public TreeNode createTree1() {
TreeNode A = new TreeNode(1);
TreeNode B = new TreeNode(2);
TreeNode C = new TreeNode(3);
TreeNode D = new TreeNode(4);
A.left = B;
A.right = C;
B.left = D;
return A;
}
public TreeNode createTree2() {
TreeNode A = new TreeNode(1);
TreeNode B = new TreeNode(2);
TreeNode C = new TreeNode(3);
TreeNode D = new TreeNode(4);
A.left = B;
A.right = C;
B.right = D;
return A;
}
public String tree2str(TreeNode root) {
StringBuilder stringBuilder = new StringBuilder();
tree2strChild(root, stringBuilder);
return stringBuilder.toString();
}
private void tree2strChild(TreeNode t, StringBuilder stringBuilder) {
if (t == null) {
return;
}
stringBuilder.append(t.val);
if (t.left != null) {
stringBuilder.append("(");
tree2strChild(t.left, stringBuilder);
stringBuilder.append(")");
} else {
if (t.right == null) {
return;
} else {
stringBuilder.append("()");
}
}
//判断右树
if (t.right != null) {
stringBuilder.append("(");
tree2strChild(t.right, stringBuilder);
stringBuilder.append(")");
} else {
return;
}
}
public static void main(String[] args) {
Solution solution = new Solution();
Solution.TreeNode root1 = solution.createTree1();
Solution.TreeNode root2 = solution.createTree2();
solution.tree2str(root2);
}
}
递归实现:
/**
* 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> list = new ArrayList<>();
if (root == null) {
return list;
}
list.add(root.val);
List<Integer> leftTree = preorderTraversal(root.left);
list.addAll(leftTree);
List<Integer> rightTree = preorderTraversal(root.right);
list.addAll(rightTree);
return list;
}
}
标签:面试题,right,TreeNode,val,int,二叉树,解析,root,left From: https://www.cnblogs.com/xumu7/p/17925910.html