如果你要去面试BAT、ATM一线互联网公司,这些二叉树题目都还不会做,那就回家好好面试思过吧,接下来我会把我自己收集的二十多道面试常见的二叉树编程题分享给大家吧,希望能为各位的面试助一臂之力。
1、计算二叉树节点个数
问题描述: 给定一颗二叉树,已知其根结点。 ①计算二叉树所有结点的个数 ②计算二叉树中叶子结点的个数 ③计算二叉树中满节点(度为2)的个数
解题思路:
当树为空时,结点个数为0;否则为根节点个数加上根的左子树中节点个数再加上根的右子树中节点的个数。
参考代码:
/**
* 递归计算树的节点个数
*/
public static int getNodeNum(TreeNode root){
if(root == null){
return 0;
}
return getNodeNum(root.left) + getNodeNum(root.right) + 1;
}
2、求树的最大层数(深度)
问题描述:
给定一颗二叉树,求树的最大层数(深度)。
参考代码:
/**
* 求树的最大层数(深度)
* */
public int maxDepth(TreeNode root){
if(root == null)
return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right))+1;
}
3、求树的最小层数(深度)
问题描述:
给定一颗二叉树,求树的最小深度:
参考代码:
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)?1 : Math.min(left, right)+1;
}
4、二叉树的前序遍历(递归算法)
问题描述:
用递归实现二叉树的前序遍历。
参考代码:
public ArrayList<Integer> preOrderRead(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);
}
5、二叉树非递归层次遍历
问题描述:
用非递归实现二叉树的层次遍历。
参考代码:
public List<Integer> preOrderRead(TreeNode root){
ArrayList<Integer> result = new ArrayList<>();
if(root == null)
return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
result.add(node.val);
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
return result;
}
6、二叉树中序遍历(递归)
问题描述:
用递归实现二叉树的中序遍历。
参考代码:
public static void midOrderRead(TreeNode root, ArrayList<Integer> res){
if(root == null){
return;
}
midOrderRead(root, res);
res.add(root.val);
midOrderRead(root, res);
}
7、二叉树中序遍历非递归
问题描述:
用非递归实现二叉树的中序遍历。
参考代码:
public static List<Integer> midOrderRead(TreeNode root){
List<Integer> res = new ArrayList<>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while(!stack.isEmpty()){
if (cur != null) {
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
}
return res;
}
8、二叉树后序遍历递归解法
问题描述:
用递归实现二叉树的后序遍历。
参考代码:
public void afterRead(TreeNode root, ArrayList<Integer> res){
if(root == null)
return ;
afterRead(root.left, res);
afterRead(root.right, res);
res.add(root.val);
}
9、非递归后序遍历二叉树
问题描述:
用非递归实现二叉树的后序遍历。
参考代码:
public List<Integer> afterReadTree(TreeNode root){
LinkedList<Integer> result = new LinkedList<>();
Deque<TreeNode> statck = new ArrayDeque<>();
TreeNode p = root;
statck.push(p);
while (!statck.isEmpty()) {
if (p != null){
statck.push(p);
result.addFirst(p.val);
p = p.right;
}else{
TreeNode node = statck.pop();
p = node.left;
}
}
return result;
}
10、判断是否是平衡二叉树
问题描述:
给定一颗二叉树,判断其是否是平衡二叉树。
参考代码:
/**
* 判断是否是平衡二叉树
* */
public boolean isBalanceTree(TreeNode root){
if(null == root)
return true;
return Math.abs(maxHigh(root.left) - maxHigh(root.right)) <= 1 &&
isBalanceTree(root.left) && isBalanceTree(root.right);
}
/**
* 获取二叉树最大深度
* */
public int maxHigh(TreeNode root){
if(null == root)
return 0;
return Math.max(maxHigh(root.left), maxHigh(root.right));
}
11、自下而上分层遍历
问题描述:
给定一颗二叉树,求出自下而上分层遍历的结果。
参考代码:
public List<List<Integer>> bottomToTop(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 cnt = queue.size();
List<Integer> level = new LinkedList<>();
for (int i = 0; i < cnt; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null)
queue.add(root.left);
if (root.right != null)
queue.add(node.right);
}
res.add(0, level);
}
return res;
}
12、 从上而下层次打印
问题描述:
给定一颗二叉树,求出从上而下分层遍历的结果。
参考代码:
public List<List<Integer>> topToBottom(TreeNode root){
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(root == null)
return res;
Queue<TreeNode> queue = new LinkedList<>();
TreeNode cur = null;
queue.add(root);
while(!queue.isEmpty()){
ArrayList<Integer> level = new ArrayList<>();
int cnt = queue.size();
for(int i=0; i<cnt; i++){
cur = queue.poll();
level.add(cur.val);
if(cur.left != null)
queue.add(root.left);
if(cur.right != null)
queue.add(root.right);
}
res.add(level);
}
return res;
}
13、 求第k层节点个数
问题描述:
给定一颗二叉树和一个整数k,求其第k层节点个数:
参考代码:
int getKLevelNum(TreeNode root, int k){
if(root == null || k <=0)
return 0;
if(root!= null && k==1)
return 1;
return getKLevelNum(root.left, k -1)+getKLevelNum(root.right, k-1);
}
14、 求第k层的叶子节点个数
问题描述:
给定一颗二叉树和一个整数k,求第k层的叶子节点个数:
参考代码:
public int getKLeafNumber(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 getKLeafNumber(root.left, k - 1)+getKLeafNumber(root.right, k - 1);
}
15、 判断两颗二叉树是否结构相同
问题描述:
给定两颗二叉树,判断其结构是否相同:
参考代码:
public static 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;
}
16、 判断是否是平衡二叉树
问题描述:
给定一颗二叉树,判断是否是平衡二叉树。
参考代码:
/**
* 判断是否是平衡二叉树
* */
public boolean isBalanceTree(TreeNode root){
if(null == root)
return true;
return Math.abs(maxHigh(root.left) - maxHigh(root.right)) <= 1 &&
isBalanceTree(root.left) && isBalanceTree(root.right);
}
/**
* 获取二叉树最大深度
* */
public int maxHigh(TreeNode root){
if(null == root)
return 0;
return Math.max(maxHigh(root.left), maxHigh(root.right));
}
17、判断是否是对称二叉树
问题描述:
给定一颗二叉树,判断是否是对称二叉树
参考代码:
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);
}
18、求二叉树的最低公共祖先
问题描述:
写算法找出二叉树树中的两个节点的最低公共祖先
参考代码:
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;
}
19、求二叉搜索树的最低公共祖先
问题描述:
写算法找出二叉搜索树树中的两个节点的最低公共祖先
参考代码:
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< p.val)
return lowestCommonAncestor(root.right, p, q);
else
return root;
}
20、求二叉树的长度或者直径
问题描述:
写算法求二叉树的长度或者直径。
参考代码:
private int path;
public int lengthHelper(TreeNode root){
if(root == null)
return 0;
int left = lengthHelper(root.left);
int right = lengthHelper(root.right);
path = Math.max(path, left + right);
return Math.max(left,right) + 1;
}
21、路径总和
问题描述:
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
参考代码:
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> ans = new ArrayList<>();
dfs(ans, new ArrayList<>(), root, sum,sum);
return ans;
}
public void dfs(List<List<Integer>> ans, List<Integer> tmpList, TreeNode root,
int sum, int remain){
if(root == null)
return;
tmpList.add(root.val);
remain = remain - root.val;
if(remain == 0 && root.left == null &&root.right == null){
ans.add(tmpList);
return;
}
dfs(ans, new ArrayList<>(tmpList), root.left, sum, remain);
dfs(ans, new ArrayList<>(tmpList), root.right, sum, remain);
}
22、求根到叶子节点数字之和(递归)
问题描述:
给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
例如,从根到叶子节点路径 1->2->3 代表数字 123。
计算从根到叶子节点生成的所有数字之和。
参考代码:
public int sumNumbers(TreeNode root) {
return sumNumbers(root, 0);
}
int sumNumbers(TreeNode root, int sum){
if(root == null)
return 0;
sum = sum * 10 + root.val;
if(root.left == null && root.right == null)
return sum;
return sumNumbers(root.left, sum) + sumNumbers(root.right,sum);
}
23、求根到叶子节点数字之和(非递归)
问题描述:
给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
例如,从根到叶子节点路径 1->2->3 代表数字 123。
计算从根到叶子节点生成的所有数字之和。
参考代码:
public int sumNumbers(TreeNode root) {
int result = 0;
Queue<TreeNode> queue = new LinkedList<>();
if(root != null)
queue.add(root);
while(!queue.isEmpty()){
root = queue.remove();
if(root.left == null && root.right == null)
result += root.val;
if(root.left != null){
root.left.val += root.val * 10;
queue.add(root.left);
}
if(root.right != null){
root.right.val += root.val * 10;
queue.add(root.right);
}
}
return result;
}