二叉树常见面试题(Leetcode)
基本操作
前序遍历
class Solution {
List<Integer> list=new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root==null)return list;
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return list;
}
}
非递归形式
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null)return list;
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
while(cur!=null||!stack.isEmpty()){
while(cur!=null){
list.add(cur.val);
stack.push(cur);
cur=cur.left;
}
cur=stack.pop();
cur=cur.right;
}
return list;
}
}
中序遍历
class Solution {
List<Integer> list=new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root==null)return list;
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
return list;
}
}
非递归版本
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null)return list;
Stack<TreeNode> stack=new Stack<>();
//TreeNode cur=root;
while(root!=null||!stack.isEmpty()){
while(root!=null){
stack.push(root);
root=root.left;
}
root=stack.pop();
list.add(root.val);
root=root.right;
}
return list;
}
}
后序遍历
class Solution {
List<Integer> list=new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)return list;
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
return list;
}
}
非递归形式
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null)return list;
Stack<TreeNode> stack=new Stack<>();
TreeNode prev=null;
while (root!=null||!stack.isEmpty()) {
while (root!=null) {
stack.push(root);
root=root.left;
}
root=stack.pop();
//prev记录已经打印过的节点
if (root.right==null||root.right==prev) {
list.add(root.val);
prev=root;
root=null;
} else {
stack.push(root);
root=root.right;
}
}
return list;
}
}
求节点个数
public int getSize2(BTnode root){
if(root==null)return 0;
return getSize2(root.left)+getSize2(root.right)+1;
}
求叶子节点个数
public int getLeafSize2(BTnode root){
if(root==null)return 0;
if(root.left==null&&root.right==null){
return 1;
}
return getLeafSize2(root.left)+getLeafSize2(root.right);
}
求第K层节点个数
public int getKLevelSize(BTnode root,int K){
if(root==null)return 0;
//递归过程中,K为1说明找到了这一层
if(K==1){
return 1;
}
return getKLevelSize(root.left,K-1)+getKLevelSize(root.right,K-1);
层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res=new ArrayList<>();
if(root==null)return res;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> list=new ArrayList<>();
//每一行的长度
int len=queue.size();
for(int i=1;i<=len;i++){
TreeNode cur=queue.poll();
list.add(cur.val);
if(cur.left!=null){
queue.offer(cur.left);
}
if(cur.right!=null){
queue.offer(cur.right);
}
}
res.add(list);
}
return res;
}
}
平衡二叉树
class Solution {
public boolean isBalanced(TreeNode root) {
if(root==null)return true;
return Math.abs(getHeight(root.left)-getHeight(root.right))<=1&&isBalanced(root.left)&&isBalanced(root.right);
}
//求高度函数
public int getHeight(TreeNode root){
if(root==null)return 0;
int left=getHeight(root.left);
int right=getHeight(root.right);
return left>right?left+1:right+1;
}
}
合并二叉树
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//特殊情况
if(root1==null)return root2;
if(root2==null)return root1;
//前中后遍历任选一个
//两树合并放在root1上
root1.left=mergeTrees(root1.left,root2.left);
root1.val=root1.val+root2.val;
root1.right=mergeTrees(root1.right,root2.right);
return root1;
}
}
对称二叉树
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null)return false;
return check(root,root);
}
public boolean check(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;
return check(p.left,q.right)&&check(p.right,q.left);
}
}
翻转二叉树
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null)return root;
TreeNode left=invertTree(root.left);
TreeNode right=invertTree(root.right);
root.left=right;
root.right=left;
return root;
}
}
二叉树的镜像
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root==null)return root;
if(root.left==null&&root.right==null)return root;
TreeNode cur=root.left;
root.left=root.right;
root.right=cur;
mirrorTree(root.left);
mirrorTree(root.right);
return root;
}
}
二叉树的深度
class Solution {
public int maxDepth(TreeNode root) {
if(root==null)return 0;
int left=maxDepth(root.left);
int right=maxDepth(root.right);
return left>right?left+1:right+1;
}
}
二叉树的最近公共祖先
思路:
三种情况:
1.p 和 qq 在 rootroot 的子树中,且分列 rootroot 的 异侧(即分别在左、右子树中);
2.p = rootp=root ,且 qq 在 rootroot 的左或右子树中;
3.q = rootq=root ,且 pp 在 rootroot 的左或右子树中;
根据 left 和 right ,可展开为四种情况;
1.当 left 和 right 同时为空 :说明 root 的左 / 右子树中都不包含 p,q ,返回 null ;
2.当 left 和 right 同时不为空 :说明 p,q 分列在 root 的 异侧 (分别在 左 / 右子树),因此 root 为
近公共祖先,返回 root ;
3.当 left 为空 ,right 不为空 :p,q 都不在 root 的左子树中,直接返回right 。具体可分为两种情况:
①p,q 其中一个在root 的 右子树 中,此时 right 指向p(假设为p );
②p,q 两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点 ;
4.当 left 不为空 , right 为空 :与情况 3. 同理;
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null)return null;
if(p==root||q==root)return root;
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
if(left==null)return right;
if(right==null)return left;
return root;
}
}
另一个树的子树
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if(t==null)return true;
if(s==null)return false;
return isSubtree(s.left,t)||isSubtree(s.right,t)||isSameTree(s,t);
}
//相同的树
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;
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
相同的树
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;
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
递增顺序搜索树
class Solution {
public TreeNode increasingBST(TreeNode root) {
List<Integer> list=new ArrayList<>();
order(root,list);
TreeNode ans=new TreeNode(0);
TreeNode cur=ans;
for(int num:list){
cur.right=new TreeNode(num);
cur=cur.right;
}
return ans.right;
}
//中序遍历
public void order(TreeNode root,List<Integer> list){
if(root==null)return;
order(root.left,list);
list.add(root.val);
order(root.right,list);
}
}
😒