題目連結:
題目意譯:
在一個二維座標平面上,我們放置了 n 個石頭在整數座標點上。每個座標點最多只能有一顆石頭。
如果某顆石頭與另一顆尚未被移除的石頭所在的列數或行數一樣,則該石頭可以被移除。
給定一個長度為 n 的陣列 stones,其中 stones[i] = [xi, yi] 代表著第 i 顆石頭的位置。回傳最多可以被移除的石頭量為何。
限制:
1 ≦ stones.length ≦ 1000
0 ≦ xi, yi ≦ 10 ^ 4
沒有兩顆石頭位於相同的座標點。
範例測資:
範例 1:
輸入: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
輸出: 5
解釋: 其中一個移除 5 顆石頭的方式為以下:
1. 移除 [2,2] 這顆石頭,因為其與 [2,1] 的列數一樣。
2. 移除 [2,1] 這顆石頭,因為其與 [0,1] 的行數一樣。
3. 移除 [1,2] 這顆石頭,因為其與 [1,0] 的列數一樣。
4. 移除 [1,0] 這顆石頭,因為其與 [0,0] 的行數一樣。
5. 移除 [0,1] 這顆石頭,因為其與 [0,0] 的列數一樣。
[0,0] 這顆石頭無法被移除,因為它不與任何尚未被移除的石頭有著相同的列數或行數。
範例 2:
輸入: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
輸出: 3
解釋: 其中一個移除 3 顆石頭的方式為以下:
1. 移除 [2,2] 這顆石頭,因為其與 [2,0] 的列數一樣。
2. 移除 [2,0] 這顆石頭,因為其與 [0,0] 的行數一樣。
3. 移除 [0,2] 這顆石頭,因為其與 [0,0] 的列數一樣。
[0,0] 和 [1, 1] 這兩顆石頭無法被移除,因為它們不與任何尚未被移除的石頭有著相同的列數或行數。
範例 3:
輸入: stones = [[0,0]]
輸出: 0
解釋: [0,0] 為平面上唯一的一顆石頭,所以你無法移除它。
解題思維:
把相同列數或相同行數的石頭們互相連在一起,可以得到類似下方圖形的架構:
而這些石頭可能可以形成多個這樣子的「群體」。
對於每個群體,我們只需要按照類似拓樸排序(Topological Sort)的方式(如
這題)來把同一群體中的石頭慢慢地移除。而如果有環的話,則隨便刪掉每個環上各自一條邊後(也就是讓這個群體所形成的圖變成一棵樹狀圖)再進行移除的步驟即可。可以看到這樣子必定可以刪到只剩下一顆石頭。
因此如果有一個群體有著 S 顆石頭,則我們可以從中移除 S - 1 顆石頭。而不同群體之間不會互相影響(因為如果會,則表示兩群體之間有石頭是相同的行或是列,進而代表著兩者應為同一群體)。
也因此,我們可以使用併查集(Union-Find Set)這個資料結構來把石頭與石頭之間的關係建立起來(即兩石頭是否位於同一群體),並且過程中可以順便統計每一個群體的大小。最後我們只需要掃過每一個群體並算出其最多可以移除多少石頭(即其大小減 1 之值),全數加總即為所求。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。