剑指 Offer 55 - II. 平衡二叉树(简单)

思路:

利用递归,先序遍历/后序遍历

 

代码:

先序遍历:

class Solution {
    public boolean isBalanced(TreeNode root) {
		//先序遍历,自顶向下
		if(root==null) return true;
		return Math.abs(Depth(root.left)-Depth(root.right))<2&&
			isBalanced(root.left)&&isBalanced(root.right);
    }
	
	private int Depth(TreeNode root){
		if(root==null)	return 0;
		return Math.max(Depth(root.left),Depth(root.right))+1;
	}
}

后序遍历:

class Solution {
    public boolean isBalanced(TreeNode root) {
		//自底向上
		int res=dfs(root);
		if(res!=-1) return true;
		else return false;
	}
	
	private int dfs(TreeNode root){
		if(root==null)	return 0;
		
		int left=dfs(root.left);
		if(left==-1)	return -1;
		
		int right=dfs(root.right);
		if(right==-1)	return -1;
		
		
		return Math.abs(left-right)<2?Math.max(left,right)+1:-1;
	}
}

 

分解:

1)先序遍历比后序遍历的时间复杂度要高,后序遍历是自底向上,而先序遍历是自顶向下

先序遍历,每一个节点(N个节点)都要往下查询一次,也就是N*logN;而后序遍历只需要查询一次,也就是N个节点

 

2)后序遍历:

剪枝有难度:

if(root==null)	return 0;
		
int left=dfs(root.left);
if(left==-1)	return -1;
		
int right=dfs(root.right);
if(right==-1)	return -1;
		

过程是先找到最下层的节点,比较左右节点

 

3)先序遍历:

过程是先比较根节点root:

Math.abs(Depth(root.left)-Depth(root.right))<2

再比较root.left和root.right:

isBalanced(root.left)&&isBalanced(root.right)

 

4)无论是先序还是后序遍历,深度+1操作都是一样的:

Math.max(Depth(root.left),Depth(root.right))+1

 

 

复杂度分析:

先序遍历

时间复杂度:O(NlogN) 最差情况下为平衡二叉树,(时间复杂度不是看是不是退化为链表,与深度无关)

遍历树所有节点,还要遍历 各子树的所有节点

总体时间复杂度 = 每层执行复杂度 × 层数复杂度 = O(N×logN)

空间复杂度:O(N) 最差情况下退化为链表,递归深度为N

 

后序遍历

时间复杂度:O(N) 遍历N个节点即可

空间复杂度:O(N) 同上

你可能感兴趣的:(力扣刷题之二叉树,力扣刷题之剑指offer,力扣刷题之深度优先遍历,二叉树,数据结构,leetcode,dfs,先序后序遍历)