寻找所有的独生节点
难度:
标签:
题目描述
代码结果
运行时间: 36 ms, 内存: 16.4 MB
// 题目思路:
// 使用Java Stream和递归结合实现,依然遍历二叉树,找到所有独生节点。
// 独生节点的定义和Java版本相同。需要注意的是,在使用Stream时,不推荐直接操作null,因此可以用Optional包装。
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Solution {
// 定义树节点类
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public List<Integer> findLonelyNodes(TreeNode root) {
return findLonelyNodesHelper(root).collect(Collectors.toList());
}
private Stream<Integer> findLonelyNodesHelper(TreeNode node) {
if (node == null) {
return Stream.empty(); // 如果当前节点为空,返回空Stream
}
Stream<Integer> lonelyNodes = Stream.empty();
if (node.left != null && node.right == null) {
lonelyNodes = Stream.of(node.left.val); // 左子节点为独生节点
} else if (node.right != null && node.left == null) {
lonelyNodes = Stream.of(node.right.val); // 右子节点为独生节点
}
// 使用Stream.concat合并当前节点的结果和子节点的结果
return Stream.concat(lonelyNodes, Stream.concat(findLonelyNodesHelper(node.left), findLonelyNodesHelper(node.right)));
}
}
解释
方法:
该题解采用了迭代方式进行二叉树的遍历,主要使用了栈(stack)来模拟递归过程,从而对二叉树进行深度优先搜索(DFS)。在遍历时,每当访问一个节点,检查其是否具有独生子节点(即只有左孩子或只有右孩子),若是,则将该子节点的值加入结果列表。通过先进后出的栈结构,先将当前节点推入栈中,然后移动到左子节点,直到左侧无子节点,再从栈中取出节点转向右子节点。这种方式确保了每个节点都被访问一次。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在迭代方式的二叉树深度优先搜索中,为什么选择使用栈(stack)而不是队列(queue)来模拟这个过程?
▷🦆
在该算法中,如果一个节点既有左子节点又有右子节点,它们是否会被考虑为独生节点?如果不是,为什么?
▷🦆
在从栈中弹出节点并转向右子节点的过程中,是否需要再次检查右子节点是否独生,并处理相应逻辑?
▷🦆
该题解中如何处理树中的节点值为null的情况,尤其是在检查子节点是否存在时?
▷