视频讲解:
后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树_哔哩哔哩_bilibili
110. 平衡二叉树
思路:平衡二叉树是指左右两边子树的高度相差不超过一,因此这道题的关键很明显,就是树的高度,再具体一点,是左右子树的高度。因此采用递归的方式对于每一个叶子节点、父节点进行左右子树高度的审核,然后逐层向上返回,即可得到该树是否为平衡二叉树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 时间复杂度O(n),空间复杂度o(1)
class Solution {
boolean flag = true;
public boolean isBalanced(TreeNode root) {
DFS(root);
return flag;
}
// 采用的是后序遍历,方法是深度优先
public int DFS(TreeNode t){
if(t == null)
return 0;
int left = DFS(t.left) + 1;
int right = DFS(t.right) + 1;
if(left - right > 1 || left - right < -1)
flag = false;
return left>right?left:right;
}
}
257. 二叉树的所有路径
思路:路径的定义是从根结点至每一个叶子节点所访问过的节点形成的序列,显然如果采用图进行表示的话,遍历路径的可视化形象是遍历方向一直向下,如果按层次进行遍历的话,那么无法确定哪个节点是属于哪条路径,父节点与子节点的关联与一条路径必须通过父节点的left和right与子节点进行判断,这大大增加了时间开销。因此,基于可视化,显然我们应当采用深度优先的遍历方式,并且根据输出的路径的样例,是符合先序遍历的思想,一条路走到底;当然中序遍历也可以进行。但是非常值得注意的是,若干条路径上可能会存在交合的部分,因此当输出了上一条路径的时候,在深度优先遍历方向返回时,一定要将上一条节点已经遍历了,且访问的指针已经经过的那些节点从路径序列中删去,这样下一条路径或者有重合的路径才可以加入进来。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 时间复杂度O(n),空间复杂度O(n)
class Solution {
List<String> ans = new ArrayList<>();
public List<String> binaryTreePaths(TreeNode root) {
// 深度优先,前序遍历
DFS(root, new ArrayList<Integer>());
return ans;
}
public void DFS(TreeNode t, List<Integer> list){
if(t == null)
return;
// 先序的遍历思路
// 中
list.add(t.val);
if(t.left == null && t.right == null){
StringBuilder builder = new StringBuilder();
for(int i=0; i<list.size(); i++){
builder.append(list.get(i));
builder.append("->");
}
builder.deleteCharAt(builder.length()-1);
builder.deleteCharAt(builder.length()-1);
ans.add(builder.toString());
}
// 左右
DFS(t.left, list);
DFS(t.right, list);
list.remove(list.size()-1);
return;
}
}
404. 左子树之和
思路:遍历整颗树,记录所有左子树中的叶子的值即可,不管是深度优先还是广度优先都可以,不管是先序、中序还是后序都可以;其次写了两种解法,递归和迭代,明显递归方法的时间开销远小于迭代法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 时间复杂度O(n),空间复杂度O(2n)
// 写了两种解法,递归和迭代,明显递归方法的时间开销远小于迭代法
class Solution {
int sum = 0;
public int sumOfLeftLeaves(TreeNode root) {
if(root == null)
return 0;
DFS(root);
return sum;
// int sum = 0;
// TreeNode[] nums = new TreeNode[2000];
// int j = -1;
// nums[++j] = root;
// while(j >= 0){
// // 中
// TreeNode t = nums[j--];
// System.out.println(t);
// // 右左,出栈之后的操作就是左右
// if(t.right != null)
// nums[++j] = t.right;
// if(t.left != null){
// nums[++j] = t.left;
// if(t.left.left == null && t.left.right == null)
// sum += t.left.val;
// }
// }
// return sum;
}
public void DFS(TreeNode t){
if(t==null)
return;
// 中
if(t.left!=null && t.left.left==null && t.left.right==null)
sum+=t.left.val;
// 左右
DFS(t.left);
DFS(t.right);
return;
}
}