leetcode
leetcode 951 ~ 1000
不邻接植花

不邻接植花

难度:

标签:

题目描述

代码结果

运行时间: 66 ms, 内存: 20.9 MB


/*
思路:
1. 使用Java Stream进行流式操作来生成答案。
2. 和Java的普通解法一样,使用贪心算法选取每个花园的花。
*/

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

public class GardenNoAdjStream {
    public int[] gardenNoAdj(int n, int[][] paths) {
        int[] answer = new int[n];
        List<Integer>[] graph = IntStream.range(0, n).mapToObj(i -> new ArrayList<Integer>()).toArray(List[]::new);
        Arrays.stream(paths).forEach(path -> {
            graph[path[0] - 1].add(path[1] - 1);
            graph[path[1] - 1].add(path[0] - 1);
        });
        IntStream.range(0, n).forEach(i -> {
            boolean[] used = new boolean[5];
            graph[i].forEach(neighbor -> used[answer[neighbor]] = true);
            answer[i] = IntStream.range(1, 5).filter(j -> !used[j]).findFirst().getAsInt();
        });
        return answer;
    }
}

解释

方法:

此题解通过首先为每个花园分配默认的花的种类1,然后根据花园之间的路径调整花的种类以满足题目要求。首先,题解构建了一个字典来存储每个花园与其相连的其他花园。字典的键是花园编号,值是与该花园连接的其他花园的列表。接着,从第二个花园开始检查(因为第一个花园默认种植第一种花),若当前花园已经记录在字典中,则获取与之相连的所有花园已种植的花的种类,然后从四种花中选择一个未被相邻花园使用的花种植在当前花园中。这样遍历所有花园后,可以得到一个符合条件的花园种花方案。

时间复杂度:

O(N + P)

空间复杂度:

O(N + P)

代码细节讲解

🦆
题解中提到,当花园数量不超过4个时,直接分配1到n的花种,这是否意味着在n<=4的情况下,任何花园之间都没有路径连接?
并不是这样。题解中当花园数量不超过4个时直接分配1到n的花种,是基于最多每个花园可以种植4种花的规则。即使存在路径连接,由于每个花园可以选择的花的种类数量等于或多于花园的总数,我们总是能为每个花园找到一个合适的花种,保证相邻花园种植的花不相同。这一处理简化了逻辑,不需要考虑具体的路径连接情况。
🦆
在构建字典存储花园的相连信息时,为什么选择在x>y的条件下处理x,反之处理y?这样的处理会对结果产生什么影响?
这种处理方式是为了确保花园编号较小的花园总是作为字典的键,而与之相连的较大编号的花园作为值中的元素。这样的处理保证了无论路径如何给出(x与y的大小关系),花园之间的连接信息都能被统一且正确地记录。这种方式不影响最终结果,只是一种确保字典构建一致性和查询效率的方法。
🦆
题解提到,每个花园最多有3条路径,但在构建字典时没有进行这种限制的检查,这是否会影响算法处理超过3条路径的情况?
题解中没有明确提到每个花园最多有3条路径的限制,因此该算法适用于任何数量的路径。若确实存在这样的限制,算法仍然可以正常工作,因为它不依赖于路径的数量来进行逻辑处理,而是依赖于能够为每个花园选择一个未被相邻花园使用的花。如果路径多于3条,只要保证选择的花不与相邻花园重复,算法仍然有效。
🦆
在选择未使用的花种时,为什么直接使用一个for循环来查找1到4中未被相邻花园使用的花,这种方法是否最优?
使用for循环查找1到4中未被相邻花园使用的花是一种简单直观的方法,可以快速遍历所有可能的花种并选择一个合适的。考虑到每个花园最多只需考虑4种花,这种方法在时间复杂度上是有效的(O(1)复杂度)。虽然存在更优化的数据结构如位运算来进一步减少时间复杂度,但在只有4种花的情况下,这种简单的方法已经足够高效,并且代码的可读性更好。

相关问题