二叉树
104.最大深度
- 后序遍历,先获得左右子树深度再计算根节点深度
class Solution {
public int maxDepth(TreeNode root) {
if(root==null)
{
return 0;
}
else
{
int left=maxDepth(root.left);
int right=maxDepth(root.right);
return Math.max(left,right)+1;
}
}
}
110.平衡二叉树判断
- 因为需要先判断两个子树再判断根节点,还是后序遍历
- 需要得知每个子树的高度,因此辅助函数计算子树树高,别忘了+1
- 遍历时如果子树不平衡,则后续的高度不用再计算了,因此设置一个-1判断,=-1时继续返回-1传递给递归最外层
- 最后主函数里判断是不是-1就行
class Solution {
public boolean isBalanced(TreeNode root) {
if (height(root)==-1)
{
return false;
}
else
{
return true;
}
}
public int height(TreeNode root)
{
if(root==null)
{
return 0;
}
else
{
int leftheight=height(root.left);
int rightheight=height(root.right);
if (Math.abs(leftheight-rightheight)>1||leftheight==-1||rightheight==-1)
{
return -1;
}
else
{
return Math.max(leftheight,rightheight)+1;
}
}
}
}
543.二叉树最长直径
- 先计算子树所以是后序遍历
- 计算左子树的最长路径和右子树的最长路径,root选个大的再+1,这样计算了每棵子树的最长直径。
- 还需要算过程中的最大值,用全局变量。
- 注意算的是直径,就求个节点数,和值没关系。
class Solution {
int maxpath=0;
public int diameterOfBinaryTree(TreeNode root) {
diametersubtree(root);
return maxpath;
}
public int diametersubtree(TreeNode root)
{
if(root==null)
{
return 0;
}
else
{
int left=diametersubtree(root.left);
int right=diametersubtree(root.right);
if((left+right)>maxpath) maxpath=left+right;
return Math.max(left,right)+1;
}
}
}
437.路径总和
- 后序遍历,刨去根节点,得到剩余的路径长,然后遍历左子树和右子树得到满足剩余路径的路径数,再加和。
- 但这样得到的永远是包括根节点的路径数
- 双重递归
- TODO: 还有哈希map的解法,前缀长度计算
class Solution {
public int pathSum(TreeNode root, int sum) {
if(root==null)
{
return 0;
}
else
{
return diametersubtree(root,sum)+pathSum(root.left,sum)+pathSum(root.right,sum);
}
}
public int diametersubtree(TreeNode root,int sum)
{
if(root==null)
{
return 0;
}
else
{
// int count=0;
// if(root.val==sum)
// {
// count=1;
// }
int count=root.val==sum?1:0;
count+=diametersubtree(root.left,sum-root.val);
count+=diametersubtree(root.right,sum-root.val);
return count;
}
}
}
注:543和437的区别:
- 以某一个节点分析,对于最长直径,假如左子树有一个最长路径,实际上最长的路径一定会加上根节点
- 但对于路径总和,只递归一次时对每个节点计算的是包含该节点的路径等于某个值的路径的个数
124.最大路径和
class Solution {
int maxpath=Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
diametersubtree(root);
return maxpath;
}
public int diametersubtree(TreeNode root)
{
if(root==null)
{
return 0;
}
else
{
int left=Math.max(diametersubtree(root.left),0);
int right=Math.max(diametersubtree(root.right),0);
if((left+right+root.val)>maxpath) maxpath=left+right+root.val;
return Math.max(left,right)+root.val;
}
}
}
101.对称二叉树
- 判断根节点是否相同
- 判断左子树和右子树是否相同
- 左子树的左子树 右子树的右子树
- 左子树的右子树 右子树的左子树
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null)
{
return true;
}
return helper(root.left,root.right);
}
private boolean helper(TreeNode t1,TreeNode t2)
{
if(t1==null&&t2==null)
{
return true;
}
if(t1==null||t2==null)
{
return false;
}
if(t1.val!=t2.val)
{
return false;
}
return helper(t1.left,t2.right)&&helper(t1.right,t2.left);
}
}
1110. 删点成林
- 链表 费劲 下次一定
98. 验证二叉搜索树(再做一次)
- 二叉搜索树,每个节点大于左子树的所有值,小于右子树的所有值
- 因此左子树的所有值小于根节点的值,把根节点的值作为右边界传过去
class Solution {
public boolean isValidBST(TreeNode root) {
return helper(root,null,null);
}
public boolean helper(TreeNode root,TreeNode min,TreeNode max)
{
if(root==null)
{
return true;
}
else
{
if(min!=null&&root.val<=min.val)
{
return false;
}
if(max!=null&&root.val>=max.val)
{
return false;
}
else
{
return helper(root.left,min,root) && helper (root.right,root,max);
}
}
}
}