题目
- 因为叶子节点不用管颜色,而其他节点都需要与它相邻节点一起凑齐三种颜色,所以选顶点的时候选至少有两个子节点的点
- 对于顶点以其中一个子节点进行深度优先的情况,如果按每层一种颜色来染色,比如 1、2、3、1、2、3...或者1、3、2、1、3、2等等,只要3个颜色按顺序选,那么除了顶点的点就一定满足条件
- 而要让顶点满足条件,如果其中一个点选了1、2、3的路线,那么另一个点只能1、3、2的路线,让顶点和子节点能凑齐1、2、3三种颜色
function process(edges, n) {
const rule1 = [1, 2, 3];
const rule2 = [1, 3, 2];
const graph = new Map();
for (let i = 0; i < n; i++) {
graph.set(i, []);
}
// 构造无向图
for (let i = 0; i < edges.length; i++) {
graph.get(edges[0]).set(edges[1]);
graph.get(edges[1]).set(edges[0]);
}
// 查找子节点数量大于2的节点,以该节点为头节点
let head = -1;
for (let i = 0; i < n; i++) {
if (graph.get(i).length >= 2) {
head = i;
break;
}
}
const colors = Array(n).fill(0);
// 只存在一个子节点或者只有一个节点的情况 0<->0
if (head === -1) {
return Array(n).fill(1);
} else {
colors[head] = 1;
// 其中一个节点方向走 1、2、3
dfs(graph, graph.get(head)[0], 1, rules1, colors);
// 剩余节点方向走 1、3、2 就能满足
for (let i = 1; i < graph.get(head).length; i++) {
dfs(graph, graph.get(head)[i], 1, rules2, colors);
}
}
// level 表示当前节点的层级
function dfs(graph, head, level, rules, colors) {
colors[head] = rules[level % 3];
for (let i = 0; i < graph.get(head).length; i++) {
const child = graph.get(head)[i];
// 因为是无向图遍历 0表示未被染色
if (colors[child] === 0) {
dfs(graph, child, level + 1, rule, colors);
}
}
}
return colors;
}