leetcode
leetcode 3001 ~ 3050
二叉搜索树染色

二叉搜索树染色

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 345 ms, 内存: 67.8 MB


/*
思路:
1. 使用 Java Stream API 对中序遍历进行处理,获取所有节点值。
2. 创建一个 Map 记录每个节点的颜色状态,初始化为蓝色。
3. 使用 Stream 处理每个操作,更新相应范围内节点的颜色。
4. 最后统计红色节点的数量。
*/

import java.util.*;
import java.util.stream.Collectors;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class BSTColoringStream {
    public int getRedNodesCount(TreeNode root, int[][] ops) {
        List<Integer> nodes = new ArrayList<>();
        Map<Integer, Boolean> colorMap = new HashMap<>();
        inOrder(root, nodes);
        nodes.forEach(val -> colorMap.put(val, false)); // Initially all nodes are blue

        Arrays.stream(ops).forEach(op ->
            nodes.stream()
                .filter(val -> val >= op[1] && val <= op[2])
                .forEach(val -> colorMap.put(val, op[0] == 1))
        );

        long redCount = colorMap.values().stream().filter(isRed -> isRed).count();
        return (int) redCount;
    }

    private void inOrder(TreeNode node, List<Integer> nodes) {
        if (node == null) return;
        inOrder(node.left, nodes);
        nodes.add(node.val);
        inOrder(node.right, nodes);
    }
}

解释

方法:

此题解通过首先将二叉搜索树的所有节点值收集到一个列表中,然后逆序遍历给定的操作列表。对于每个操作,它使用二分搜索确定操作影响的值范围在列表中的位置,然后根据操作类型更新红色节点的计数器。操作完成后,对列表进行切片以删除已处理的值范围。该方法利用了二叉搜索树的有序性和二分搜索来有效处理节点范围。

时间复杂度:

O(m log n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么题解中选择使用逆序遍历操作列表 `ops[::-1]` 而不是正序遍历?
题解中选择逆序遍历操作列表的原因是为了确保在处理每个操作时,操作影响的节点范围不会被后续的操作影响。如果从后向前应用操作,可以避免在删除或修改节点值范围时对未来操作产生影响。这种方法允许我们在处理每个操作时,只考虑当前操作的影响,而不需要担心后续操作可能对已处理的节点范围造成的干扰。
🦆
在操作列表逆序遍历后,直接移除已处理的值范围 `values = values[:i] + values[j:]` 是否会影响后续操作的正确性?
在逆序遍历操作列表时,直接移除已处理的值范围不会影响后续操作的正确性。由于我们是从操作列表的最后一个操作开始处理,并且每次处理都是针对当前状态下的值范围,所以一旦一个范围被处理(例如染色或计数),它就不再需要被后续的操作考虑。这种方法确保了每个操作都是在一个更新后的环境中独立执行,从而避免了对未来操作的干扰。
🦆
题解中提到使用深度优先搜索(DFS)来收集所有节点值,这样收集的节点值是否一定是有序的,为什么?
题解中使用深度优先搜索(DFS)来收集所有节点值,确实会得到一个有序的列表。这是因为在二叉搜索树(BST)中,如果按照中序遍历(即先遍历左子树,然后访问根节点,最后遍历右子树)的方式进行,遍历得到的值序列是按照从小到大的顺序排列的。因此,DFS在此处确保了值的有序性,这是利用二叉搜索树的性质得到的结果。

相关问题