You have N
gardens, labelled 1
to N
. In each garden, you want to plant one of 4 types of flowers.
paths[i] = [x, y]
describes the existence of a bidirectional path from garden x
to garden y
.
Also, there is no garden that has more than 3 paths coming into or leaving it.
Your task is to choose a flower type for each garden such that, for any two gardens connected by a path, they have different types of flowers.
Return any such a choice as an array answer
, where answer[i]
is the type of flower planted in the (i+1)
-th garden. The flower types are denoted 1, 2, 3, or 4. It is guaranteed an answer exists.
Example 1:
Input: N = 3, paths = [[1,2],[2,3],[3,1]]
Output: [1,2,3]
Example 2:
Input: N = 4, paths = [[1,2],[3,4]]
Output: [1,2,1,2]
Example 3:
Input: N = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
Output: [1,2,3,4]
Note:
1 <= N <= 10000
0 <= paths.size <= 20000
- No garden has 4 or more paths coming into or leaving it.
- It is guaranteed an answer exists.
算法思路:
就是简单的添加颜色,任意两点不能重复使用同一种颜色,貌似很简单,但是题目有坑,题目传进来的是paths这种非标准图,在使用贪心算法,会出现后续的边对前面的着色产生影响,比如[1,2] [2,3] [3,4] [2,3] [4,1]这种情况。因此应该从全局处理,例如对1号顶点处理时,现将1号顶点的相邻结点都找到,然后如果相邻结点已经有颜色了,把这些颜色去掉,在剩下的颜色中为1号顶点选一个颜色。为方便上述操作,首先将非标准图转换成广义邻接表形式。
class Solution {
private:
vector<int> getColorResult(vector<vector<int>>& g) {
int n = g.size();
vector<int> res(n, -1); //-1: not colored
for(int i = 0; i < n; i++) {
vector<bool> color(4, false); //false: not used
//mark the color which has used
for(auto v : g[i]) {
if(res[v] != -1) color[res[v] - 1] = true;
}
//find a not been used color
for(int j = 0; j < 4; j++) {
if(color[j] == false) {
res[i] = j + 1;
break;
}
}
}
return res;
}
public:
vector<int> gardenNoAdj(int N, vector<vector<int>>& paths) {
vector<vector<int>> g(N);
//build graph
for(auto& edge : paths){
g[edge[0] - 1].emplace_back(edge[1] - 1); //similar to push_back, but more efficient
g[edge[1] - 1].emplace_back(edge[0] - 1);
}
return getColorResult(g);
}
};