Leetcode 1042:不邻接植花(超详细的解法!!!)

N个花园,按从1N标记。在每个花园中,你打算种下四种花之一。

paths[i] = [x, y]描述了花园x到花园y的双向路径。

另外,没有花园有 3 条以上的路径可以进入或者离开。

你需要为每个花园选择一种花,使得通过路径相连的任何两个花园中的花的种类互不相同。

以数组形式返回选择的方案作为答案answer,其中answer[i]为在第(i+1)个花园中种植的花的种类。花的种类用 1, 2, 3, 4 表示。保证存在答案。

示例 1:

输入:N = 3, paths = [[1,2],[2,3],[3,1]]
输出:[1,2,3]

示例 2:

输入:N = 4, paths = [[1,2],[3,4]]
输出:[1,2,1,2]

示例 3:

输入:N = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
输出:[1,2,3,4]

提示

  • 1 <= N <= 10000
  • 0 <= paths.size <= 20000
  • 不存在花园有 4 条或者更多路径可以进入或离开。
  • 保证存在答案。

解题思路

由于这个问题的数据量很大,并且只是easy难度,所以不难想到是通过贪心来处理。思路非常简单,从前向后遍历path,遍历的过程中,检查遍历到的点周围颜色情况,然后挑一个没用过的颜色放入即可。

class Solution:
    def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]:
        res = [0] * N
        m = [[] for _ in range(N + 1)]
        for x, y in paths:
            m[x].append(y)
            m[y].append(x)
            
        for i in range(1, N+1):
            used = set()
            for j in m[i]:
                used.add(res[j-1])
            for j in range(1, 5):
                if j not in used:
                    res[i-1] = j
                    break
        return res

一个pythonic的写法

class Solution:
    def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]:
        res = [0] * N
        m = [[] for _ in range(N + 1)]
        for x, y in paths:
            m[x].append(y)
            m[y].append(x)
        for i in range(1, N+1):
            res[i-1] = ({1, 2, 3, 4} - {res[j-1] for j in m[i]}).pop()
        return res

那么这么做为什么是对的呢?仔细想来这么做一定是对的。因为没有花园有 3 条以上的路径可以进入或者离开,如果将整个结构看成一个图的话(每个花园看做一个节点),那么每个花园的度数最多是3,那么当前颜色一定可以和周围不一样啊。

reference:

https://leetcode.com/problems/flower-planting-with-no-adjacent/discuss/290858/JavaC%2B%2BPython-Greedily-Paint

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(go)