104.二叉树的最大深度
题目链接:104.二叉树的最大深度
文档讲解:代码随想录/二叉树的最大深度
视频讲解:视频讲解-二叉树的最大深度
状态:已完成(2遍)
解题过程
看到题目的第一想法
用层序遍历遍历出二叉树每层的节点,最后return二叉树有多少层即可。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
let ans = [],queue = [];
if(root == null)return [];
else{
queue.push(root);
while(queue.length!=0){
let smallAns = [];
let len = queue.length;
for(let i =0;i<len;i++){
let node = queue.shift();
smallAns.push(node.val);
node.left&&queue.push(node.left);
node.right&&queue.push(node.right);
}
ans.push(smallAns);
}
return ans.length;//最后返回长度就行
}
};
提交没有问题。
看完代码随想录之后的想法
递归的代码还真确实比较精简,这里用后序来让子节点的高度返回给父节点进行处理。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
//使用递归的方法 递归三部曲
//1. 确定递归函数的参数和返回值
const getdepth = function(node) {
//2. 确定终止条件
if(node === null) {
return 0;
}
//3. 确定单层逻辑
let leftdepth = getdepth(node.left);
let rightdepth = getdepth(node.right);
let depth = 1 + Math.max(leftdepth, rightdepth);
return depth;
}
return getdepth(root);
};
递归的难点还是在思考用哪种方式,这道题先将左右子节点的深度获取到最后返回给父节点,所以用后序。
总结
深度是任意一个节点到根节点的距离,用前序;高度是二叉树中任意一个节点到叶子结点的距离,用后序。根节点的高度就是二叉树的最大深度。
111.二叉树的最小深度
题目链接:111.二叉树的最小深度
文档讲解:代码随想录/二叉树的最小深度
视频讲解:视频讲解-二叉树的最小深度
状态:已完成(1遍)
解题过程
看到题目的第一想法
脑子已经变成层序遍历的形状了。这道题我想到的还是用层序遍历,在遍历每一层的时候,判断如果出现有一个节点它既没有左子结点又没有右子节点,那就说明它是离根节点最近的叶子结点。那么在遍历完这一层的时候直接停止遍历,返回层序遍历数组的长度,即为二叉树的最小深度。
手搓一版如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
if(root == null)return 0;
let ans = [],queue=[];
queue = [root];
while(queue.length){
let flag = 0;
let len = queue.length;
let smallAns = [];
while(len--){
let node = queue.shift();
smallAns.push(node.val);
if(!node.left&&!node.right){//如果左右子节点都没有的话
flag = 1;//立个flag
}else{
node.left&&queue.push(node.left);
node.right&&queue.push(node.right);
}
}
ans.push(smallAns);
if(flag)break;//检查有没有flag出现,如果有,说明出现了一个左右子节点都没有的叶子结点,当前深度即为最小深度
}
return ans.length;
};
提交直接成功,层序遍历真是公公又式式。
看完代码随想录之后的想法
讲解里的首选解法依旧是后序递归。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
if(!root) return 0;
// 到叶子节点 返回 1
if(!root.left && !root.right) return 1;
// 只有右节点时 递归右节点
if(!root.left) return 1 + minDepth(root.right);
// 只有左节点时 递归左节点
if(!root.right) return 1 + minDepth(root.left);
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
};
总结
这道题跟上一道题类似,求最小深度既是求最小的高度,那么用后序递归来求根节点的最小高度即可。
一定要注意这道题和最大深度的区别,因为要看叶子结点,所以不能鲁莽的直接将左右两边递归值进行取最大值。
222.完全二叉树的节点个数
题目链接:222.完全二叉树的节点个数
文档讲解:代码随想录/完全二叉树的节点个数
视频讲解:视频讲解-完全二叉树的节点个数
状态:已完成(2遍)
解题过程
看到题目的第一想法
继续公式化层序遍历。层序遍历完之后,将最后一层的节点数加上除去最后一层之外的所有层数的节点数即可。
手搓一版如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var countNodes = function(root) {
let queue=[],ans=[];
if(root == null)return 0;
queue = [root];
while(queue.length){
let smallAns = [];
let len = queue.length;
while(len--){
let node = queue.shift();
smallAns.push(node.val);
node.left&&queue.push(node.left);
node.right&&queue.push(node.right);
}
ans.push(smallAns);
}
let ansNum = ans[ans.length-1].length + 2**(ans.length-1)-1;
return ansNum;
};
提交没有问题,不过差点超时。
看完代码随想录之后的想法
这道题能用层序遍历如此简便做出来还是因为完全二叉树的特性,讲解部分的普通二叉树思路更值得学习。
讲解代码如下:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var countNodes = function(root) {
//递归法计算二叉树节点数
// 1. 确定递归函数参数
const getNodeSum = function(node) {
//2. 确定终止条件
if(node === null) {
return 0;
}
//3. 确定单层递归逻辑
let leftNum = getNodeSum(node.left);
let rightNum = getNodeSum(node.right);
return leftNum + rightNum + 1;
}
return getNodeSum(root);
};
总结
依旧温习递归三部曲:
- 确定递归的参数;
- 确定终止条件;
- 确定单层递归逻辑。