持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
题目:第54题,要求找出二叉搜索树的第k大的节点。
第55题对应两个子问题,第一个问题是求一颗二叉树的深度,第二个是判断一棵树是否是平衡二叉树。
解题思路
首先来看第54题,根据二叉搜索树的特性,本题的解决很简单。我们需要注意一个重要的知识点,一颗二叉搜索树的中序遍历即为有序序列。本题要求找出第k大的节点,那么我们通过右子树-根节点-左子树的方式遍历整棵树就可以得到序列的逆序。当遍历到第k个节点的时候就可以截断,可得代码如下:
private int cur = 0;
private int value = 0;
public int kthLargest(TreeNode root, int k) {
search(root, k);
return value;
}
public void search(TreeNode root, int k){
if(root == null) return ;
search(root.right, k);
cur ++ ;
if(cur == k){
value = root.val;
return;
}
search(root.left, k);
}
之后来看第55题的第一问,求二叉树的深度,可以通过层序遍历的方式来得到树的深度,每当一层中的元素遍历完成即深度加1,简单的实现方式是使用队列来记录节点,按照先左子树后右子树的方式将节点入队,之后依次弹出即可,此外还需要使用一个额外的变量来记录本层的节点是否已经遍历完,根据当前队列的元素数量来更新每层的节点数量,可得代码如下:
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int maxDepth = 0;
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
int cur = 1;
while(!deque.isEmpty()){
TreeNode poll = deque.poll();
cur --;
if(poll.left!=null) deque.offer(poll.left);
if(poll.right!=null) deque.offer(poll.right);
if(cur == 0){
cur = deque.size();
maxDepth ++;
}
}
return maxDepth;
}
另一种方式是使用递归,通过比较左右子树的深度来得到整棵树的深度,可得代码如下:
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right))+1;
}
第二问是判断一棵树是否是平衡二叉树,平衡二叉树要求左子树右子树的深度不能大于1,并且所有的子树都需要满足这一条件,实际上通过这个性质就很容易可以得到本题的答案,可得代码如下:
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
if(Math.abs(maxDepth(root.left)-maxDepth(root.right))<=1){
return isBalanced(root.left) && isBalanced(root.right);
}
return false;
}
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right))+1;
}