有N
个花园,按从1
到N
标记。在每个花园中,你打算种下四种花之一。
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
解题思路
由于这个问题的数据量很大,并且只是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
如有问题,希望大家指出!!!