平衡二叉树
思路:定义一个函数,传入node,返回值int,如果该节点平衡则返回该节点的高度,如果不平衡则返回-1。
class Solution {
public boolean isBalanced(TreeNode root) {
int res = height(root);
if(res==-1){
return false;
}else{
return true;
}
}
public int height(TreeNode root){
//如果当前节点的平衡,返回其高度,否则返回-1
//求高度 所以需要用到后序遍历
if(root==null){
return 0;
}
int leftHeight = height(root.left);
if(leftHeight==-1){
return -1;
}
int rightHeight = height(root.right);
if(rightHeight==-1){
return -1;
}
int res = Math.abs(leftHeight-rightHeight);
if(res>1){
return -1;
}else{
return 1+Math.max(leftHeight,rightHeight);
}
}
二叉树的所有节点数
用的是前序遍历(深度优先),res作为全局遍历,只要遍历到一个节点就加一
class Solution {
int res=0;
public int countNodes(TreeNode root) {
if(root==null){
return 0;
}
res+=1;
countNodes(root.left);
countNodes(root.right);
return res;
}
}
二叉树的所有路径
前序+回溯,这里要注意递归和回溯要放在一起
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
dfs(root, path, res);
return res;
}
private void dfs(TreeNode root, List<Integer> path, List<String> res) {
path.add(root.val);
if(root.left==null&&root.right==null){
StringBuilder sb = new StringBuilder();
for(int i=0;i<path.size()-1;i++){
sb.append(path.get(i)).append("->");
}
sb.append(path.get(path.size()-1));
res.add(sb.toString());
return;
}
if(root.left!=null){
dfs(root.left,path,res);
path.remove(path.size()-1);
}
if(root.right!=null){
dfs(root.right,path,res);
path.remove(path.size()-1);
}
}
}
仿照前序遍历(深度优先)的代码来写,不同的是每个节点访问的时候不是把他打印出来,而是先把他存储起来,到叶子结点的时候再添加到集合中,最后返回集合的值
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
dfs(root, "", res);
return res;
}
private void dfs(TreeNode root, String path, List<String> res) {
//如果为空,直接返回
if (root == null)
return;
//如果是叶子节点,说明找到了一条路径,把它加入到res中
if (root.left == null && root.right == null) {
res.add(path + root.val);
return;
}
//如果不是叶子节点,在分别遍历他的左右子节点
dfs(root.left, path + root.val + "->", res);
dfs(root.right, path + root.val + "->", res);
}
二叉树的左叶子之和
先序遍历,如果说当前节点有左子树,而且左子树是个叶子节点,就让他加到全局变量里面。
突然发现用二叉树用前序遍历(深度优先)特别好理解,因为基本只需要看根怎么移动,怎么操作,后面的交给左右子树去遍历操作,不过因为是先序,有些操作还是做不了,比如求树的最大深度,需要找到左右的最大深度然后+1,这时候得用后序。
\TODO 先序,后序的使用场景区别,暂时觉得还是先序还是更好理解
class Solution {
int res=0;
public int sumOfLeftLeaves(TreeNode root) {
return dfs(root);
}
public int dfs(TreeNode root){
if(root==null){
return 0;
}
if(root.left!=null&&root.left.left==null&&root.left.right==null){
res=res+root.left.val;
}
dfs(root.left);
dfs(root.right);
return res;
}
}