问题描述
947. Most Stones Removed with Same Row or Column
On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone.
Now, a move consists of removing a stone that shares a column or row with another stone on the grid.
What is the largest possible number of moves we can make?
Example 1:
Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]] Output: 5
Example 2:
Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]] Output: 3
Example 3:
Input: stones = [[0,0]] Output: 0
Note:
1 <= stones.length <= 1000
0 <= stones[i][j] < 10000
------------------------------------------------------------
题意
给定坐标系中若干个点的坐标,如果一个点所在的行或所在列存在别的点,则可以将该点删去。问最多可以删去多少个点。
------------------------------------------------------------
思路
如果两点同行或同列,则在两个点之间建立一条边,如此建图,得到图的关联矩阵。问题转化为求图的连通分量,如果求出连通分量,则可以删掉的点为所有连通分量所含的点数-1之和。用bfs求连通分量。
注意:贪心法不断选取度最小的点删去不能得到本题的解。在此给出一个图作为反例:
------------------------------------------------------------
代码
class Solution {
public:
int removeStones(vector<vector<int>>& stones) {
int x, y, i, cnt = 0, ans = 0, n = stones.size(), u, v;
list<int> X[10005], Y[10005];
list<int> graph[1005];
bool vis[1005] = {};
list<int>::iterator iter;
i = 0;
for (auto stone : stones)
{
x = stone[0];
y = stone[1];
X[x].push_back(i);
Y[y].push_back(i++);
}
i = 0;
for (auto stone : stones)
{
x = stone[0];
y = stone[1];
iter = graph[i].end();
iter = graph[i].insert(iter, X[x].begin(), X[x].end());
graph[i].insert(iter, Y[y].begin(), Y[y].end());
i++;
}
for (i=0; i<n; i++)
{
if (!vis[i])
{
queue<int> q;
q.push(i);
vis[i] = true;
cnt = 1;
while (!q.empty())
{
u = q.front();
q.pop();
for (auto v : graph[u])
{
if (!vis[v])
{
q.push(v);
vis[v] = true;
cnt++;
}
}
}
ans += cnt - 1;
}
}
return ans;
}
};