值为 1 的节点数
难度:
标签:
题目描述
代码结果
运行时间: 124 ms, 内存: 28.0 MB
// Leetcode 2445: Count Nodes with Value 1 using Java Stream
// 题目思路:
// 给定一个二叉树,求二叉树中节点值为 1 的节点数量。
// 使用递归函数将所有节点收集到一个列表中,然后利用Java Stream进行过滤和统计。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public int countNodesWithValueOne(TreeNode root) {
// 创建一个列表来存储所有节点
List<TreeNode> nodes = new ArrayList<>();
// 调用递归函数将所有节点添加到列表中
collectNodes(root, nodes);
// 使用流过滤值为1的节点并计数
return (int) nodes.stream().filter(node -> node.val == 1).count();
}
private void collectNodes(TreeNode node, List<TreeNode> nodes) {
if (node == null) return;
nodes.add(node);
collectNodes(node.left, nodes);
collectNodes(node.right, nodes);
}
}
解释
方法:
题解采用了翻转操作的方法来计算值为1的节点数。初始化一个列表 flip,其长度为 n+1,所有元素初始值为0,用来记录每个位置的翻转状态。遍历输入的 queries,每遇到一个元素,就将对应 flip 中的位置进行异或操作(0变1,1变0),表示翻转状态。然后从索引2开始,利用父节点的翻转状态影响到当前节点,即每个节点的最终状态由它自身的翻转以及它的父节点的翻转状态决定。最后,统计 flip 列表中值为1的元素数量,即为最终的结果。
时间复杂度:
O(q + n)
空间复杂度:
O(n)
代码细节讲解
🦆
在算法中,为什么选择从索引2开始遍历,而不是从索引1或更小的索引开始?
▷🦆
你是如何确定每个节点的最终翻转状态只受其自身和其父节点影响,而不是其他祖先节点也有影响?
▷🦆
在实现中,如果节点的索引超过了 n 的范围,但仍被 queries 引用,这种情况如何处理,或者说算法是如何确保不会出现这种情况的?
▷🦆
算法中使用异或操作来标记节点翻转状态的理由是什么?是否有其他方式可以实现相同的功能,比如使用加法或布尔数组切换?
▷