Minimum Height Trees

本此選做的題目是有關於圖與樹的應用Minimum Height Trees,大致的要求如下

The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Example 1:

Given n = 4edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3

return [1]

Example 2:

Given n = 6edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

     0  1  2
      \ | /
        3
        |
        4
        |
        5

return [3, 4]

剛開始對於這道題的做法似懂非懂,後來經過一些額外的資料輔助,知道可以使用unodered_set<int>透過給定的邊來構造出一個關於每個點的vector,由example 1舉例,1 node 有相鄰的三個點,unordered_set<int>就是透過鏈表的方式以1為頭指向相鄰的邊1->0->2->3,透過這個原理我可以先將樹、邊轉換成鏈表的形式:

vector<unordered_set<int>> v(n);
    for(int i = 0; i < edges.size();++i)
    {
       v[edges[i].first].insert(edges[i].second);
       v[edges[i].second].insert(edges[i].first);
    }

    在這之前先給出判斷語句確定頂點數n是否為0或1

     vector<int> ans;
        if(!n)
            return ans;
        if(n == 1)
        {
            ans.push_back(0);
        }


    關於樹的遍歷已經最小樹的根可以透過寬度搜索(BFS)來實現,透過由下往上的遍歷,具體實現如下,首先先確定鏈表中size()為1的頂點,因為這些點頂可以確定是樹葉

     vector<int> leaves;
        for(int i = 0; i < n; ++i)
            if(v[i].size() == 1)
               leaves.push_back(i);

    接著是BFS的實現,由樹葉往上搜索,先便利樹葉所有鄰近的頂點,並先刪除樹葉,如果在樹葉刪除之後,新琳的點的size為1的話,那確認他是新的樹葉將他加入newleaves中,在下次循環中再以相同的方法檢測,此外,當我們沒有檢測到新的newleaves時,意味者當前的leaves克能是構成最短樹的根結點。

    while(true)
         {
             vector<int> newleaves;
             for(int l : leaves)
             {
                  for(int i : v[l])
                  {
                      v[i].erase(l);
                      if(v[i].size() == 1)
                         newleaves.push_back(i);
                  }
             }
             if(newleaves.size() == 0)
                return leaves;
             leaves = newleaves;
         }


    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值