代码随想录第17天:110.平衡二叉树 、257. 二叉树的所有路径 、404.左叶子之和

110:平衡二叉树

1、递归法:

我最开始想的实现方法是两层递归,一层递归求高度,另一层判断是否是平衡二叉树。

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root==null) {
			return true;
		}
		int left = getHeight(root.left);
		int right = getHeight(root.right);
		if (Math.abs(left-right)>1) {
			return false;
		}
		return isBalanced(root.left) && isBalanced(root.right);
    }

    public int getHeight(TreeNode node) {
		if (node==null) {
			return 0;
		}
		int left = getHeight(node.left);
		int right = getHeight(node.right);
		return Math.max(left, right)+1;
	}
}

看了题解之后,发现其实可以合并成一个递归,如果不是平衡二叉树的话高度返回-1即可。

class Solution {
    public boolean isBalanced(TreeNode root) {
      return getHeight2(root)==-1?false:true;
    }

    public int getHeight2(TreeNode node) {
		if (node==null) {
			return 0;
		}
		int left = getHeight2(node.left);
		if (left==-1) {
			return -1;
		}
		int right = getHeight2(node.right);
		if (right==-1) {
			return -1;
		}
		if (Math.abs(left-right)>1) {
			return -1;
		}
		return Math.max(left, right)+1;
	}
}

迭代法看了一下直接放弃了

257:二叉树的所有路径

1、递归法:

1)递归函数参数和返回值确定:因为所求的是二叉树的所有路径,递归的话应该考虑前序遍历每次到达叶子节点的时候把当前路径输出,故参数主要包括三个,一个node节点用于遍历,paths列表用于存储当前遍历路径上节点的值,list列表用于存储符合要求的路径。

2)递归终止条件:当遍历到叶子节点,也就是当前节点的左右节点都为空的时候,输出当前遍历的路径。

3)单层递归逻辑:按照中左右的前序遍历逻辑,每当遍历一个节点的时候,都需要进行一次回溯。

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();
		if (root==null) {
			return res;
		}
		List<Integer> path = new ArrayList<>();
		search(root, path, res);
		return res;
    }
    public void search(TreeNode node, List<Integer> paths , List<String> list) {
		paths.add(node.val);
		
		//递归出口
		if (node.left==null && node.right==null) {
			//输出该条路径
			StringBuilder sBuilder = new StringBuilder();
			for (int i = 0; i < paths.size()-1; i++) {
				sBuilder.append(paths.get(i));
				sBuilder.append("->");
			}
			sBuilder.append(paths.get(paths.size()-1));
			list.add(sBuilder.toString());
			return;
		}
		
		if (node.left!=null) {
			search(node.left, paths, list);//递归
			//回溯,如果已经到了递归出口,说明已经找到了一条路径,此时则需要回溯,退回到前一个节点处
			paths.remove(paths.size()-1);
		}
		if (node.right!=null) {
			search(node.right, paths, list);
			paths.remove(paths.size()-1);
		}
	}
}

2、迭代法

迭代法按照先序遍历的方式,每次把节点入栈,同时还把当前的路径入栈,每次把路径pop,同时也把节点pop,这样可以遍历到每个叶子结点,输出相应的路径即可。

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
     	List<String> res = new ArrayList<>();
		if (root==null) {
			return res;
		}
		Stack<Object> stack = new Stack<>();
		stack.push(root);
		stack.push(root.val+"");
		while (!stack.isEmpty()) {
			String path = (String) stack.pop();
			TreeNode node = (TreeNode) stack.pop();
			if (node.left==null && node.right==null) {
				res.add(path);
			}
			if (node.right!=null) {
				stack.push(node.right);
				stack.push(path+"->"+node.right.val);
			}
			if (node.left!=null) {
				stack.push(node.left);
				stack.push(path+"->"+node.left.val);
			}
		}
		return res;
    }
    
}

404:左叶子之和

左叶子:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点

递归法:

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
    	if (root==null) {
			return 0;
		}
		if (root.left==null && root.right==null) {
			return 0;
		}
		int left = sumOfLeftLeaves(root.left);
		if (root.left!=null && root.left.left==null && root.left.right==null) {
			left = root.left.val;
		}
		int rignt = sumOfLeftLeaves(root.right);
		return left+rignt;
    }
    
}

迭代法:

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
    	if (root==null) {
			return 0;
		}
		if (root.left==null && root.right==null) {
			return 0;
		}
		int depth = 0;
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()) {
			TreeNode node = stack.pop();
			if (node.left!=null && node.left.left==null && node.left.right==null) {
				depth += node.left.val;
			}
			if (node.right!=null) {
				stack.push(node.right);
			}
			if (node.left!=null) {
				stack.push(node.left);
			}
		}
		return depth;
    }
    
}

这题感觉迭代法比递归法好理解。

总结:今天总体感觉还行,递归可能还是不算很熟练,还需再加强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值