LeetCode周賽#112 Q3 Most Stones Removed with Same Row or Column(連通分量)
阿新 • • 發佈:2018-11-29
問題描述
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;
}
};