Open azl397985856 opened 2 years ago
图 dfs 染色
class Solution {
//染色 dfs
public:
bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
// 构建邻接矩阵
dp = vector<vector<int>>(n);
for (vector<int>& dislike : dislikes) {
dp[dislike[0]-1].emplace_back( dislike[1] -1);
dp[dislike[1]-1].emplace_back( dislike[0] -1);
}
// 初始化颜色表
color = vector<int>(n, 0); // 0 未染色, 1 染成红色 -1染成绿色
for (int i = 0; i < n; i++) {
if (color[i] == 0 && !dfs(i, 1)) {
return false;
}
}
return true;
}
// 尝试给i染成color
bool dfs(int cur, int c) {
color[cur] = c;
// 遍历所有的死对头
for (int fighter : dp[cur]) {
// 死对头已经分配了, 并且等于我的队列
if (color[fighter] == c) {
return false;
}
// 尝试给死对头分配我的另一个队列
if (color[fighter] == 0 && !dfs(fighter, -c)) {
return false;
}
}
return true;
}
private:
vector<int> color;
vector<vector<int>> dp;
};
空间:O(N2)
时间: O(N)
二分图,用visited标记当前染色情况,0 1 -1,对每个节点都进行BFS(不一定说连通图),如果下个要求的颜色和下个节点的颜色冲突,就返回False
class Solution(object):
def possibleBipartition(self, n, dislikes):
"""
:type n: int
:type dislikes: List[List[int]]
:rtype: bool
"""
graph = collections.defaultdict(list)
for d in dislikes:
graph[d[0]].append(d[1])
graph[d[1]].append(d[0])
visited = [0 for i in range(n + 1)]
for i in range(n + 1):
if visited[i] != 0:
continue
q = deque()
q.append(i)
visited[i] = 1
while q:
cur = q.popleft()
curLabel = visited[cur]
nextLabel = -1 * curLabel
for nextNode in graph[cur]:
# not colored
if visited[nextNode] == 0:
visited[nextNode] = nextLabel
q.append(nextNode)
elif visited[nextNode] != nextLabel:
return False
# print(visited)
return True
time O(V + E) space O(V)
Graph, DFS, node coloring Person <-> Node P1 and P2 dislike each other <-> Node 1 and Node 2 share one edge, and they can be drawed with different two colors. Other people can not be colored with two different colors.
class Solution {
List<Integer>[] graph;
int[] color;
public boolean possibleBipartition(int n, int[][] dislikes) {
graph = new ArrayList[n + 1];
color = new int[n + 1];
for(int i = 1; i <= n; i++) {
graph[i] = new ArrayList<Integer>();
}
for(int[] dislike: dislikes) {
graph[dislike[0]].add(dislike[1]);
graph[dislike[1]].add(dislike[0]);
}
for(int i = 1; i <= n; i++) {
if(color[i] == 0 && !dfs(1, i)) {
return false;
}
}
return true;
}
private boolean dfs(int c, int node) {
if(color[node] != 0) {
return color[node] == c;
}
color[node] = c;
for(int n: graph[node]) {
if(!dfs(-c, n)) {
return false;
}
}
return true;
}
}
Complexity Analysis
使用dfs函数,查找每个节点能够正确分组的位置,调整节点正确的分组
dfs函数中判断,
语言支持:Python3
Python3 Code:
class Solution:
def dfs(self, graph, colors, i, color, n):
colors[i] = color
for j in range(n):
# 如果i j相互不喜欢
if graph[i][j] == 1:
# 相互不喜欢 不能使用同种颜色
if colors[j] == color:
return False
# 如果j还没有分配组 给他分配合适的组
if colors[j] == 0 and not self.dfs(graph, colors, j, -1*color, n):
return False
# 当前分配位置正确 可以分配
return True
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
"""
将人分成两个组
"""
# 使用邻接矩阵来表示图 1表示不喜欢 0表示没有不喜欢
graph = [[0]*n for _ in range(n)]
colors = [0] * n
for a,b in dislikes:
graph[a-1][b-1] = 1
graph[b-1][a-1] = 1
for i in range(n):
if colors[i] == 0 and not self.dfs(graph, colors, i, 1, n):
return False
return True
复杂度分析
令 V 为图的节点个数,E为边的个数。
class Solution:
def dfs(self, g, i, c, colors):
colors[i] = c
# for it's connector v, try to color -1*c
for j in g[i]:
if colors[j] == c:
return False
elif colors[j] == 0 and not self.dfs(g, j, -1*c, colors):
return False
return True
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
g = collections.defaultdict(list)
for x, y in dislikes:
g[x-1].append(y-1)
g[y-1].append(x-1)
colors = [0] * n
for i in range(n):
if colors[i] == 0 and not self.dfs(g, i, 1, colors):
return False
return True
time O(V+E)
space O(V+E)
886. 可能的二分法
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/possible-bipartition/
前置知识
题目描述
每个人都可能不喜欢其他人,那么他们不应该属于同一组。
形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。
当可以用这种方法将每个人分进两组时,返回 true;否则返回 false。
示例 1:
输入:N = 4, dislikes = [[1,2],[1,3],[2,4]] 输出:true 解释:group1 [1,4], group2 [2,3] 示例 2:
输入:N = 3, dislikes = [[1,2],[1,3],[2,3]] 输出:false 示例 3:
输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]] 输出:false
提示:
1 <= N <= 2000 0 <= dislikes.length <= 10000 dislikes[i].length == 2 1 <= dislikes[i][j] <= N dislikes[i][0] < dislikes[i][1] 对于dislikes[i] == dislikes[j] 不存在 i != j