演算法題——冗餘連線

HD0117發表於2024-10-27

684.冗餘連線

題幹

樹可以看成是一個連通且 無環 的 無向 圖。

給定往一棵 n 個節點 (節點值 1~n) 的樹中新增一條邊後的圖。新增的邊的兩個頂點包含在 1 到 n 中間,且這條附加的邊不屬於樹中已存在的邊。圖的資訊記錄於長度為 n 的二維陣列 edges ,edges[i] = [ai, bi] 表示圖中在 ai 和 bi 之間存在一條邊。

請找出一條可以刪去的邊,刪除後可使得剩餘部分是一個有著 n 個節點的樹。如果有多個答案,則返回陣列 edges 中最後出現的那個。


輸入: edges = [ [1,2], [1,3], [2,3] ]
輸出: [2,3]


輸入: edges = [ [1,2], [2,3], [3,4], [1,4], [1,5] ]
輸出: [1,4]

思路

對於一個包含n個節點的圖,至少需要n-1條邊才能使圖連線起來,本題中共有n條邊,n個節點,那麼出現的第一條使得圖成環的邊就是最後一條使得圖成環的邊,即該邊就是答案。

在無環圖中考慮連通性使用並查集,在有向圖中考慮依賴性使用dfs、bfs或拓撲排序。

vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        int len=edges.size();
        vector<int> p(len+1);
        for(int i=1; i<=len; ++i)
        {
            p[i]=i;
        }
        for(auto &edge : edges)
        {
            int v1=edge.front(), v2=edge.back();
            //查詢兩個節點v1和v2是否屬於同一個集合
            if(Find(p,v1)!=Find(p,v2))
            {
                Union(p,v1,v2);
            }
            else
            {
                return edge;
            }
        }
        return vector<int>{};
    }
    int Find(vector<int>& p, int index)
    {
        //如果index的parent不是index,說明index已經歸到某個集合中,繼續查詢index的parent
        //最頂層的index的parent是其本身
        if(p[index]!=index)
        {
            p[index]=Find(p,p[index]);
        }
        return p[index];
    }
    void Union(vector<int> &p, int v1, int v2)
    {
        //定義聯合為將v1所在的集合的父節點設定為v2所在集合的父節點,這樣兩個集合就連線了
        p[Find(p,v1)]=Find(p,v2);
    }

相關文章