题目描述
在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。
现在,move 操作将会移除与网格上的某一块石头共享一列或一行的一块石头。
我们最多能执行多少次 move 操作?
示例 1:
输入:stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]] 输出:5
示例 2:
输入:stones = [[0,0],[0,2],[1,1],[2,0],[2,2]] 输出:3
示例 3:
输入:stones = [[0,0]] 输出:0
提示:
1 <= stones.length <= 1000
0 <= stones[i][j] < 10000
解题思路
可以将坐标上的每一块石头看作是一个结点,move操作看作是两个结点之间的一条边,于是就转换成连通分量中边的总数
BFS:
int len;
int vis[1001];
void bfs(vector<vector<int>>& G,vector<int>& u,int s){
vis[s] = 1;
queue<vector<int>> que;
que.push(u);
while(!que.empty()){
vector<int> tmp = que.front();
que.pop();
for(int i=0;i<len;i++){
if((vis[i] == 0) && (tmp[0] == G[i][0] || tmp[1] == G[i][1])){
vis[i] = 1;
que.push(G[i]);
}
}
}
}
int removeStones(vector<vector<int>>& stones) {
len = stones.size();
if(len <= 1) return 0;
int count = 0;
memset(vis,0,sizeof(vis));
for(int i=0;i<len;i++){
if(vis[i]) continue;
bfs(stones,stones[i],i);
count++;
}
return len - count;
}
DFS:
void dfs(vector<vector<int>>& G,vector<int>& u,int s){
vis[s] = 1;
for(int i=0;i<len;i++){
if(vis[i] == 0){
if(u[0] == G[i][0] || u[1] == G[i][1]){
dfs(G,G[i],i);
}
}
}
}
int removeStones(vector<vector<int>>& stones) {
len = stones.size();
if(len <= 1) return 0;
int count = 0;
memset(vis,0,sizeof(vis));
for(int i=0;i<len;i++){
if(vis[i]) continue;
dfs(stones,stones[i],i);
count++;
}
return len - count;
}