今天的题目在于理解前序位置、后序位置等关键位置的重要性。
一、二叉树的最大深度 104
1、分析
首先可以将总体问题,分解成小问题,即当前结点的最大深度,应该是左右分支深度更大者的值加一。所以我们用递归的思想,对一个结点做出计算最大深度的操作,剩下的结点递归算法会对他们做相同的操作。
这题较为简单,可以见具体代码
2、代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root: #base case 递归的出口
return 0
left = self.maxDepth(root.left) #得到左子树的最大深度
right = self.maxDepth(root.right) #得到右子树的最大深度
return max(left,right)+1 #取左右子树中最大者然后+1即为当前结点的最大深度
JS
/**
* 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) {
if(root===null){
return 0;
}
let left = maxDepth(root.left);
let right = maxDepth(root.right);
return Math.max(left,right)+1;
};
二、二叉树的直径 543
1、分析
首先注意到,最长的直径可能不穿过根节点。我们考虑用一个外部变量res记录结果,然后针对每个结点求以该结点为根的直径(就是左子树最大深度,加上右子树的最大深度),依次比较更新res值。
对于每个结点求最大深度,又可以分解为求该结点下的左右子树最大深度,然后二者中最大值+1即为所求。
基于以上两点我们采用有返回值的递归搭配外部变量求解。由于我们需要先知道左右子树的结果,关键代码放在后序遍历位置进行。
具体见代码和注释。
2、代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
self.res = 0 #用于存放最终结果的外部变量
def helper(node):
if not node: #base case 递归出口
return 0
left = helper(node.left) #求左子树最大深度
right = helper(node.right) #求右子树最大深度
self.res = max(self.res,left+right) #将当前节点的直径与res比较, 保证res始终是最大直径
return max(left,right)+1 #取左右子树深度中更大的值然后加一,即为当前节点的最大深度
helper(root)
return self.res
JS
/**
* 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 diameterOfBinaryTree = function(root) {
let res = 0;
var helper = function(node){
if(node===null){
return 0;
}
let left = helper(node.left);
let right = helper(node.right);
res = Math.max(res,right+left);
return Math.max(left,right)+1;
}
helper(root);
return res;
};
二叉树的前序遍历 144
1、分析
常规前序遍历,用递归实现,先对当前结点进行操作,然后再对左右子节点进行操作。具体见代码。
2、代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def helper(node):
if node:
res.append(node.val)
helper(node.left)
helper(node.right)
helper(root)
return res
JS
/**
* 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 preorderTraversal = function(root) {
let res = [];
let helper = function(node){
if(node!==null){
res.push(node.val);
helper(node.left);
helper(node.right);
}
}
helper(root);
return res;
};