1. 程式人生 > >LeetCode周賽#112 Q3 Most Stones Removed with Same Row or Column(連通分量)

LeetCode周賽#112 Q3 Most Stones Removed with Same Row or Column(連通分量)

題目來源:https://leetcode.com/contest/weekly-contest-112/problems/most-stones-removed-with-same-row-or-column/

問題描述

 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. 1 <= stones.length <= 1000
  2. 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;
    }
};