leetcode
leetcode 2851 ~ 2900
游乐园的游览计划

游乐园的游览计划

难度:

标签:

题目描述

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

代码结果

运行时间: 707 ms, 内存: 70.6 MB


/*
 * 思路:
 * 1. 使用Stream API来构建图并处理数据。
 * 2. 遍历每个项目A,查找符合条件的路径并计算喜爱值。
 * 3. 使用Stream的map和filter方法来筛选和计算数据。
 */

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

public class MaxHappinessStream {
    public int maxHappiness(int[][] edges, int[] value) {
        int n = value.length;
        Map<Integer, List<Integer>> graph = IntStream.range(0, n)
                .boxed()
                .collect(Collectors.toMap(i -> i, i -> new ArrayList<>()));

        Arrays.stream(edges).forEach(edge -> {
            graph.get(edge[0]).add(edge[1]);
            graph.get(edge[1]).add(edge[0]);
        });

        return IntStream.range(0, n).map(A -> graph.get(A).stream()
                .flatMap(B -> graph.get(B).stream()
                        .filter(C -> C != A && graph.get(C).contains(A))
                        .map(C -> new int[]{A, B, C}))
                .mapToInt(abc -> {
                    int A1 = abc[0], B1 = abc[1], C1 = abc[2];
                    Set<Integer> visited = new HashSet<>(Arrays.asList(A1, B1, C1));
                    return graph.get(A1).stream()
                            .flatMap(B2 -> graph.get(B2).stream()
                                    .filter(C2 -> !visited.contains(B2) && !visited.contains(C2) && graph.get(C2).contains(A1))
                                    .mapToInt(C2 -> value[A1] + value[B1] + value[C1] + value[B2] + value[C2])
                            ).max().orElse(0);
                }).max().orElse(0)).max().orElse(0);
    }
}

解释

方法:

题解的核心思想是通过构建图的邻接表来快速查找节点的相邻节点,从而高效地找到可能的A-B-C-A形式的游玩路径。首先,它通过统计每个节点的度和构建邻接表来初始化图结构。然后,通过对每个节点作为A尝试找到B和C,使得存在A-B-C-A的路径,并记录这样的三元组。对于每个节点,使用一个排序列表来保持值最大的几个B-C对。这样,在最后的步骤中,可以高效地检查和计算所有可能的A-B-C-A和A-B'-C'-A组合的最大喜爱值总和。

时间复杂度:

O(N*d^2 + M)

空间复杂度:

O(N + M)

代码细节讲解

🦆
如何确保在构建邻接表时,通过使度小的点指向度大的点的策略,可以优化算法的性能?
这种策略主要是为了减少在图遍历过程中的冗余操作,特别是在寻找A-B-C-A型路径时。具体来说,当一个度数较小的节点指向一个度数较大的节点时,可以减少遍历的次数,因为较小度数的节点作为出发点时,其连接的选项较少,从而减少了需要检查的路径数量。这样,每次从一个度数较小的节点开始遍历,只需要较少的操作就可以检查到其所有相邻的较高度数节点。这不仅提高了算法的效率,也减少了无效的计算,尤其是在图较为稠密时,此策略能显著减少计算量。
🦆
在处理节点A时,如何避免重复计算相同的B-C对,以及如何确保B和C不会与A相同?
在算法中,通过维护一个访问数组`vis`来跟踪哪些节点已经被作为B访问过,可以有效避免在找C时重复选择相同的B。当遍历到节点A的邻接节点B时,将B标记为已访问。接着在找C时只考虑那些未被标记的节点,这样就可以确保B和C不会与A相同,也避免了B和C的重复。每次完成A的B-C对探索后,需要重置访问数组,以便于下一个节点的探索不会受到影响。
🦆
对于每个节点A,如果其邻接节点B的数量非常少,是否会影响到找到有效的B-C对的概率?如何处理这种情况?
确实,如果节点A的邻接节点数量很少,这将直接影响找到有效的B-C对的概率,因为可选的B和C较少,可能无法形成有效的A-B-C-A路径。在这种情况下,虽然不能改变图的结构,但可以通过算法逻辑优化来尽量提高查找效率。例如,可以专门对那些度数较小的节点进行优化处理,如在找到一个有效的B-C对后立即中断当前搜索,减少无效的计算。同时,也可以通过预处理和缓存一些结果来加速对这类节点的查询。

相关问题