leecode算法《257. 二叉树的所有路径》详解有注释,简单明了。
原题内容
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
输入:
1
/ \
2 3
\
5
输出: [“1->2->5”, “1->3”]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
审题:
这个题可以用深度优先搜索 解决所有路径的问题
方法一–》迭代
自己用栈实现的,和官方的对比了一下确实代码写的啰嗦,大家可以指正
思路就是 利用栈的特性:先进后出来实现
大家如果大不知道深度优先搜索的办法可以先去百度下或者看下视屏,要不然确实不好理解
我给出图解
自己的代码:
public static void main(String[] args) {
TreeNode root1 = new TreeNode(1);
TreeNode root2 = new TreeNode(2);
root1.left = root2;
/* TreeNode root3 = new TreeNode(3);
TreeNode root5 = new TreeNode(5);
root2.right=root5;
root1.left=root2;
root1.right=root3;*/
System.out.println(binaryTreePaths2(root1));
}
private static List<String> binaryTreePaths2(TreeNode root) {
// 创建结果集
LinkedList<String> paths = new LinkedList<>();
// 创建栈
Stack<TreeNode> stack = new Stack<>();
// 创建到每个节点路径的栈
Stack<String> pathStack = new Stack<>();
// 创建哈希判断给节点是否已经访问过。访问的不再访问
HashSet<String> hashSet = new HashSet<>();
// 如果节点为空之直接返回空字符串
if (root == null) {
return paths;
} else {
// 定义初始路径也就是开始点
String path = root.val + "";
// 将根节点压入栈,并且添加到hashset里面
stack.push(root);
hashSet.add(root.toString());
// 将根节点路径压入一个栈
pathStack.push(path);
// 如果栈不为空 一直疯狂循环
while (!stack.isEmpty()) {
// 取出栈顶元素
TreeNode pop = stack.pop();
// 取出栈顶元素路径
String result = pathStack.pop();
// 如果栈顶元素的左右孩子都是null,直接将路径添加上去
if (pop.right == null && pop.left == null) {
paths.add(result);
} else {
result = result + "->";
// 如果左孩子不为空,并且没有出现过name 压入栈
if (pop.left != null && !hashSet.contains(pop.left.toString())) {
pathStack.push(result + pop.left.val);
hashSet.add(pop.left.toString());
stack.push(pop.left);
}
// 如果右孩子不为空,并且没有出现过name 压入栈
if (pop.right != null && !hashSet.contains(pop.right.toString())) {
pathStack.push(result + pop.right.val);
hashSet.add(pop.right.toString());
stack.push(pop.right);
}
}
}
}
return paths;
}
官方题解迭代代码:(没仔细研究以后有时间再看。)
public List<String> binaryTreePaths(TreeNode root) {
LinkedList<String> paths = new LinkedList();
if (root == null)
return paths;
LinkedList<TreeNode> node_stack = new LinkedList();
LinkedList<String> path_stack = new LinkedList();
node_stack.add(root);
path_stack.add(Integer.toString(root.val));
TreeNode node;
String path;
while (!node_stack.isEmpty()) {
node = node_stack.pollLast();
path = path_stack.pollLast();
if ((node.left == null) && (node.right == null))
paths.add(path);
if (node.left != null) {
node_stack.add(node.left);
path_stack.add(path + "->" + Integer.toString(node.left.val));
}
if (node.right != null) {
node_stack.add(node.right);
path_stack.add(path + "->" + Integer.toString(node.right.val));
}
}
return paths;
}
方法一–》递归
最直观的方法是使用递归。在递归遍历二叉树时,需要考虑当前的节点和它的孩子节点。如果当前的节点不是叶子节点,则在当前的路径末尾添加该节点,并递归遍历该节点的每一个孩子节点。如果当前的节点是叶子节点,则在当前的路径末尾添加该节点后,就得到了一条从根节点到叶子节点的路径,可以把该路径加入到答案中。
private static List<String> binaryTreePaths(TreeNode root, String path, List<String> result) {
// 如果节点不为空进行
if (root != null) {
// 先将本节点的这个路径加入到path中
path = path + root.val;
// 如果本节点的左孩子和右孩子全部为空,那么递归结束
if (root.left == null && root.right == null) {
// 将结果添加到集合中
result.add(path);
} else {
// 如果本节点的左孩子和右孩子不是为空,需要加上“-》”
path = path + "->";
// 递归左孩子
binaryTreePaths(root.left, path, result);
// 递归右孩子
binaryTreePaths(root.right, path, result);
}
}
return result;
}
public static List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<>();
return binaryTreePaths(root, "", result);
}
···