看到这个题之后思考了许久,然后想到层次遍历,灵光一闪,似乎好像可以,直接开干。
看了许多题解,感觉我自己的这种思想还挺新颖的,时间复杂度的话只遍历了一遍,取值也是以下标形式取址的。所以整体应该是O(N)的复杂度吧。然后除了遍历用的队列,以及结果集所需的List集合,也没有额外的开销了。emm自我感觉还不错,记录下来,与君共享。
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<>(); //用来记录返回的结果集
if(root != null){
Queue<TreeNode> queue = new LinkedList<>();//这个队列用来做二叉树的层序遍历。
queue.offer(root);//头节点入队。
String temp = String.valueOf(root.val); //记录下此时的节点信息,因为它是结果的一部分,接下来后面增加节点的时候就需要在这个基础上进行累加。
result.add(temp);//加入结果集。
root.val = 0; // 记录下这个部分所在结果集的下标。因为这个原本的数字我已经记录下来了,这个变量就直接被我复用了。
while(!queue.isEmpty()){
int len = queue.size();//每一层的节点数
while(len != 0){//在这一层内进行遍历。
TreeNode cur = queue.poll();
temp = result.get(cur.val);
if(cur.left != null){
queue.offer(cur.left);
result.set(cur.val,temp + "->" + cur.left.val);//将原本的结果集的数据进行增加,因为它有孩子。
cur.left.val = cur.val;//同样记录下这个部分所在的结果集的下标。
cur.val = result.size();//为下一步做准备,如果它还有一个孩子的话,就需要在结果集上加一条数据了。
}
if(cur.right != null){
queue.offer(cur.right);
if(cur.val == result.size()){//果不其然还有一个孩子,加一条数据。
result.add(new String());
}
result.set(cur.val,temp + "->" + cur.right.val);//对这条数据进行一个拼接,加上这个孩子。
cur.right.val = cur.val;//同样记录这天数据所在结果集的下标。
}
len--;
}
}
}
return result;
}
}
另外再附上代码随想录上看的两种解法:
迭代法:
class Solution {
/**
* 迭代法
*/
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<>();
if (root == null)
return result;
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) {
result.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 result;
}
}
递归法:
class Solution {
/**
* 递归法
*/
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
if (root == null) {
return res;
}
List<Integer> paths = new ArrayList<>();
traversal(root, paths, res);
return res;
}
private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
paths.add(root.val);
// 叶子结点
if (root.left == null && root.right == null) {
// 输出
StringBuilder sb = new StringBuilder();
for (int i = 0; i < paths.size() - 1; i++) {
sb.append(paths.get(i)).append("->");
}
sb.append(paths.get(paths.size() - 1));
res.add(sb.toString());
return;
}
if (root.left != null) {
traversal(root.left, paths, res);
paths.remove(paths.size() - 1);// 回溯
}
if (root.right != null) {
traversal(root.right, paths, res);
paths.remove(paths.size() - 1);// 回溯
}
}
}