leetcode 684. 冗餘連線(圖中找環)

湖北二師的鹹魚發表於2020-10-21

在本問題中, 樹指的是一個連通且無環的無向圖。

輸入一個圖,該圖由一個有著N個節點 (節點值不重複1, 2, …, N) 的樹及一條附加的邊構成。附加的邊的兩個頂點包含在1到N中間,這條附加的邊不屬於樹中已存在的邊。

結果圖是一個以邊組成的二維陣列。每一個邊的元素是一對[u, v] ,滿足 u < v,表示連線頂點u 和v的無向圖的邊。

返回一條可以刪去的邊,使得結果圖是一個有著N個節點的樹。如果有多個答案,則返回二維陣列中最後出現的邊。答案邊 [u, v] 應滿足相同的格式 u < v。

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

思路:
就是找父節點以及合併兩個節點的過程
優化
藉助一個rank,這個rangk代表節點的高度(可以這麼理解),將小的高度節點嫁接到高的節點上面。

程式碼

class Solution {

private:
vector<int> parent; 
vector<int> rank; 

int find_parent(int x)
{
    int x_root=x;
    while(parent[x_root]!=-1)
    {
        x_root=parent[x_root];
    }
    return x_root;
}
bool Union(int x,int y)
{
    int x_root=find_parent(x);
    int y_root=find_parent(y);

    if(x_root==y_root)
    {
        return false;
    }
    //優化,防止形成的鏈太長
    if(rank[x_root]>rank[y_root])
    {
        parent[y_root]=x_root;
    }
    else if(rank[x_root]<rank[y_root])
    {
        parent[x_root]=y_root;
    } else if(rank[x_root]==rank[y_root])
    {
        parent[x_root]=y_root;
        rank[y_root]++;
    }   
    return true;
}

public:
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        vector<int>  ret_v;
        int mi;
        int mj;
        int N=edges.size();
        parent=vector<int> (N+1,-1);//剛開始父節點都是-1
        rank=vector<int>(N+1,1);//剛開始每個節點的高度預設為1
        for(int i=0;i<edges.size();i++)
        {
            if(Union(edges[i][0],edges[i][1])==false)
            {
                mi=edges[i][0];
                mj=edges[i][1];
            }
        }
        return ret_v=vector<int>{mi,mj};
        
    }
};

相關文章