前往
大廳
主題

LeetCode - 0924. Minimize Malware Spread 解題心得

Not In My Back Yard | 2023-11-23 12:00:14 | 巴幣 0 | 人氣 77

題目連結:


題目意譯:
你被給定一個有著 n 個節點的網路,其以一個 n × n 的鄰接矩陣(Adjacency Matrix)graph 所表示,其中如果 graph[i][j] == 1 則代表著第 i 個節點與第 j 個節點是直接相連的。

在整數陣列 initial 中有些節點一開始就被惡意軟體感染。而每當有兩個直接相連的節點且至少其中一個已經被惡意軟體感染,則兩個節點都將被惡意軟體感染。這個擴散將持續到沒有節點可以被感染為止。

假設 M(initial) 是在惡意軟體的擴散停止之後在整個網路中被感染的節點個數。而我們將會從 initial 中移除恰好一個節點。

回傳在被移除之後將會最小化 M(initial) 的節點。如果有多個節點可以被移除來最小化 M(initial),回傳索引值最小者。

注意到如果有一個節點從 initial 所代表的最初感染者中被移除,它仍有可能會在之後的擴散之中被感染到。

限制:
n == graph.length
n == graph[i].length
2 ≦ n ≦ 300
graph[i][j] 只會是 0 或是 1。
graph[i][j] == graph[j][i]
graph[i][i] == 1
1 ≦ initial.length ≦ n
0 ≦ initial[i] ≦ n - 1
在 initial 中的所有整數彼此相異。



範例測資:
範例 1:
輸入: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
輸出: 0

範例 2:
輸入: graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2]
輸出: 0

範例 3:
輸入: graph = [[1,1,1],[1,1,1],[1,1,1]], initial = [1,2]
輸出: 1


解題思維:
可以看到會被某個最初感染者節點感染到的節點,可以視為它們兩個節點是在「同一個集合」之中。而題目給定的 graph 中每一條「邊」都可以視為把兩個集合合併在一起。因此我們可以使用併查集(Union-Find Set,參見這題)來處理。然後我們可以為每一個集合多新增兩個資訊——一個是儲存有幾個最初感染者在這個集合之中,另一個是索引值最小的感染者為何。

可以看到,如果每一個集合的最初感染者之數量要嘛大過 1、要嘛等於 0,則代表不管我們移除哪一個節點,最後能感染到的節點數都一樣。此時可以看到所求為最初感染者中索引值最小者。

而如果有集合的最初感染者數量為 1,則我們可以移除該節點並使該集合不會被感染到。而為了最小化最後的感染節點數,我們需要找出那些最初感染者數量恰好為 1 且集合大小最大者(這樣一來才能盡可能消掉最多的感染數)。而如果還是有平手的狀況,則挑出索引值最小的最初感染者即可。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作