这题是自己的知识盲区。
自己做了没有做出来,而且认为我的思路是正确的,找不出错误在哪儿,错误代码在最下面,希望以后能够找出来错误在哪儿吧。
首先这一题一开始最重要的思路,也是自己没有想到的,就是把一对一的不喜欢的关系转换为邻接表,也就是看成图的问题。这自己没有想到确实不应该。一直有些苦恼的怎么快速找到不喜欢的关系的问题用邻接表可以轻松解决。
然后思路应该是这样:对于每一个还没有确定在哪个group里面的,将它放入任意一个group,然后将它所有和它相邻的(不喜欢的)放入另一个group,再将与它们相邻的放入另一个group,一直这样下去,所以需要一个queue。也就是每次处理完一整个互相有关系的人群。
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
vector<vector<int>> adj(N+1, vector<int>());//用个邻接表把关系表示出来。用空间换取效率。这是很重要的思路
for (auto& dislike : dislikes) {
adj[dislike[0]].push_back(dislike[1]);
adj[dislike[1]].push_back(dislike[0]);
}
vector<int> colors(N+1, 0);
queue<int> q;
for (int i = 1; i <= N; ++i) {
if (colors[i] != 0)
continue;
colors[i] = 1;//对于一个新的来说,放进哪个都是一样的
q.push(i);
while (!q.empty()) {
int cur = q.front();
q.pop();
for (int nb : adj[cur]) {
if (colors[nb] == 0) {
colors[nb] = colors[cur] == 1? 2 : 1;
q.push(nb);
} else {
if (colors[nb] == colors[cur])
return false;
}
}
}
}
return true;
}
};
这是bfs,应该可以用dfs:
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
vector<vector<int>> adj(N+1, vector<int>());//用个邻接表把关系表示出来。用空间换取效率。这是很重要的思路
for (auto& dislike : dislikes) {
adj[dislike[0]].push_back(dislike[1]);
adj[dislike[1]].push_back(dislike[0]);
}
vector<int> colors(N+1, 0);
for (int i = 1; i <= N; ++i)
if (colors[i] == 0)
if (!dfs(adj, colors, i, 1))
return false;
return true;
}
private:
bool dfs(vector<vector<int>>& adj, vector<int>& colors, int idx, int color) {
if (colors[idx] != 0) {
if (colors[idx] == color)
return true;
else
return false;
}
colors[idx] = color;
for (int nb : adj[idx])
if (!dfs(adj, colors, nb, 3-color))
return false;
return true;
}
};
然后这里是我一开始的思路的解法,主要的缺点就是没有用邻接表,但是我认为思路应该是正确的,不知道为什么不对。
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
unordered_set<int> s1, s2;
return dfs(dislikes, 0, s1, s2);
}
private:
bool dfs(vector<vector<int>>& dislikes, int idx, unordered_set<int>& s1, unordered_set<int>& s2) {
if (idx == dislikes.size())
return true;
auto& dislike = dislikes[idx];
int num1 = dislike[0], num2 = dislike[1];
if ((isInSet(num1, s1) && isInSet(num2, s1)) || (isInSet(num1, s2) && isInSet(num2, s2)))
return false;
if ((isInSet(num1, s1) && isInSet(num2, s2)) || (isInSet(num1, s2) && isInSet(num2, s1)))
return dfs(dislikes, idx+1, s1, s2);
if (isInSet(num1, s1)) {
s2.insert(num2);
if (dfs(dislikes, idx+1, s1, s2))
return true;
s2.erase(num2);
return false;
}
if (isInSet(num2, s1)) {
s2.insert(num1);
if (dfs(dislikes, idx+1, s1, s2))
return true;
s2.erase(num1);
return false;
}
if (isInSet(num1, s2)) {
s1.insert(num2);
if (dfs(dislikes, idx+1, s1, s2))
return true;
s1.erase(num2);
return false;
}
if (isInSet(num2, s2)) {
s1.insert(num1);
if (dfs(dislikes, idx+1, s1, s2))
return true;
s1.erase(num1);
return false;
}
s1.insert(num1);
s2.insert(num2);
if (dfs(dislikes, idx+1, s1, s2))
return true;
s1.erase(num1);
s1.insert(num2);
s2.erase(num2);
s2.insert(num1);
return dfs(dislikes, idx+1, s1, s2);
}
bool isInSet(int num, unordered_set<int>& s) {
return s.find(num) != s.end();
}
};
另外,785题和这题一样,可以看一眼