拓撲排序變種題:Leetcode310最小高度樹

拓撲排序變種題:Leetcode310最小高度樹

問題:

在這裏插入圖片描述
在這裏插入圖片描述

思路:

借用了BFS的思想,一次性將度爲1的節點全部刪除,不斷進行此操作,直至只剩2個或1個節點


正確性證明:
無向無環圖A在刪除度爲1的結點後得到無向無環圖B。可以證明,圖A所成最小高度樹TreeA是由圖B所成的最小高度樹TreeB接上被刪除結點後構成的。反證法:圖B所成的樹TreeB如果不是最小高度樹,那麼存在圖B的最小高度樹TreeB’,TreeB’的高度比TreeB更小。那麼TreeB’接上被刪除結點後高度比TreeA更小,這與TreeA是最小高度樹矛盾。

既然圖A的最小高度樹是由圖B的最小高度樹接上被刪除的結點所成。那麼圖A的最小高度樹的根結點與圖B的最小高度樹的根結點是相同的,因爲,接上被刪除的結點不會成爲根結點,否則相比不成爲根結點的高度還要高1。因此找圖A的最小高度樹的根結點演變爲找圖B的最小高度樹的根結點。


使用隊列,首先將度爲1的節點全部入隊,計算隊列長度
之後進入循環,循環的終止條件爲剩下的節點數<=2。
在循環中先將節點數減去隊列長度得到剩餘節點數,接下來每次將隊列中元素pop出,並將已pop出的元素的度賦爲0(該節點已被刪除),對於該元素鄰接表中的所有未被刪除的元素(度不爲0),將其度-1,若減1後度爲1,將其加入隊列

代碼:

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        vector<int> ans;
        if( n==1 )
        {
            ans.push_back(0);
            return ans;
        }
        if( n==2 )
        {
            ans.push_back(0);
            ans.push_back(1);
            return ans;
        }
        int* indegree;
        indegree=(int*)malloc( n*sizeof(int) );
        int i;
        for( i=0;i<n;i++ )
            indegree[i]=0;
        for( i=0;i<edges.size();i++ )
        {
            indegree[ edges[i][0] ]++;
            indegree[ edges[i][1] ]++;
        }
        vector<vector<int>> table;
        for( i=0;i<n;i++ )
            table.push_back( vector<int>() );
        for( i=0;i<edges.size();i++ )
        {
            table[ edges[i][1] ].push_back( edges[i][0] );
             table[ edges[i][0] ].push_back( edges[i][1] );
        }
        queue<int> queue;
        for( i=0;i<n;i++ )
        {
            if( indegree[i]==1 )
            {
                queue.push(i);
            }
        }
        int len=queue.size();
        int vertex;
        while( n>2 )
        {   
            n-=len;
            while( len-- )
            {
                vertex=queue.front();
                queue.pop();
                indegree[vertex]=0;
                for( i=0;i<table[vertex].size();i++ )
                {   
                    if( indegree[ table[vertex][i] ]!=0 ) 
                    {   
                        if( --indegree[ table[vertex][i] ]==1 )
                            queue.push( table[vertex][i] ); 
                    }   
                }
            }
            len=queue.size();
        }
        while( queue.size()!=0 )
        {
            vertex=queue.front();
            queue.pop();
            ans.push_back(vertex);
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章