日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 310. 最小高度树(图 聪明的BFS,从外向内包围)

發(fā)布時間:2024/7/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 310. 最小高度树(图 聪明的BFS,从外向内包围) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 暴力BFS
      • 2.2 聰明的BFS

1. 題目

對于一個具有樹特征的無向圖,我們可選擇任何一個節(jié)點作為根。圖因此可以成為樹,在所有可能的樹中,具有最小高度的樹被稱為最小高度樹。給出這樣的一個圖,寫出一個函數(shù)找到所有的最小高度樹并返回他們的根節(jié)點。

格式

該圖包含 n 個節(jié)點,標記為 0 到 n - 1。給定數(shù)字 n 和一個無向邊 edges 列表(每一個邊都是一對標簽)。

你可以假設沒有重復的邊會出現(xiàn)在 edges 中。由于所有的邊都是無向邊, [0, 1]和 [1, 0] 是相同的,因此不會同時出現(xiàn)在 edges 里。

示例 1: 輸入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]0|1/ \2 3 輸出: [1]示例 2: 輸入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]0 1 2\ | /3|4|5 輸出: [3, 4]說明:根據(jù)樹的定義,樹是一個無向圖,其中任何兩個頂點只通過一條路徑連接。 換句話說,一個任何沒有簡單環(huán)路的連通圖都是一棵樹。 樹的高度是指根節(jié)點和葉子節(jié)點之間最長向下路徑上邊的數(shù)量。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/minimum-height-trees
著作權(quán)歸領扣網(wǎng)絡所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

2. 解題

2.1 暴力BFS

  • 從每個節(jié)點開始BFS,記錄高度,選擇最小的高度的起點即可
  • 節(jié)點很多的時候,會超時
class Solution {unordered_map<int,unordered_set<int>> g;vector<int> vertex;queue<int> q; public:vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {for(auto& e : edges){g[e[0]].insert(e[1]);g[e[1]].insert(e[0]);}bool visited[n];int minh = INT_MAX, h;for(int i = 0; i < n; i++){memset(visited, 0, sizeof(visited));h = 0;visited[i] = true;q.push(i);BFS(h,visited);if(h < minh){minh = h;vertex.clear();vertex.push_back(i);}else if(h == minh)vertex.push_back(i);}return vertex;}void BFS(int& h, bool* visited){int tp, size;while(!q.empty()){size = q.size();while(size--){tp = q.front();q.pop();for(const int& id : g[tp]){if(!visited[id]){q.push(id);visited[id] = true;}}}h++;}} };

優(yōu)化下

  • 是最外圍的節(jié)點?是最外圍的,不用從他開始BFS,高度肯定不是最小的
  • 見以下代碼,還是超時!!!
class Solution {unordered_map<int,unordered_set<int>> g;vector<int> vertex;queue<int> q;vector<int> lastLv; public:vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {for(auto& e : edges){g[e[0]].insert(e[1]);g[e[1]].insert(e[0]);}bool visited[n];bool outSide[n];//是最外圍的節(jié)點?是最外圍的,不用從他開始BFS,高度肯定不是最小的memset(outSide, 0, sizeof(outSide));int minh = INT_MAX, h = 0;for(int i = 0; i < n; i++){if(minh > 2 && outSide[i])continue;memset(visited, 0, sizeof(visited));h = 0;visited[i] = true;q.push(i);BFS(h,visited,outSide);if(h < minh){minh = h;vertex.clear();vertex.push_back(i);}else if(h == minh)vertex.push_back(i);}return vertex;}void BFS(int& h, bool* visited, bool* outSide){int tp, size;while(!q.empty()){size = q.size();lastLv.clear();while(size--){tp = q.front();q.pop();for(const int& id : g[tp]){if(!visited[id]){q.push(id);visited[id] = true;lastLv.push_back(id);}}}h++;}for(auto id : lastLv)outSide[id] = true;} };

2.2 聰明的BFS

  • 最低的高度樹,可能的root只有1個或者2個(相當于把一個數(shù)組平分兩半,奇偶可能)
  • 那么從圖中最外圍的節(jié)點,開始找(出入度為1),把所有的出入度為1的節(jié)點push進入隊列
  • 一層層的剝離節(jié)點,到遍歷的節(jié)點只剩下2個或者1時,即找到答案
class Solution { public:vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {if(n == 1)return {0};int i, tp, size;unordered_map<int,unordered_set<int>> g;//圖的鄰接表vector<int> vertex;queue<int> q;//隊列for(auto& e : edges){g[e[0]].insert(e[1]);//g[e[1]].insert(e[0]);}for(i = 0; i < n; i++)if(g[i].size() == 1)//出入度1,最外層的節(jié)點q.push(i);//進入隊列while(n > 2)//剩余節(jié)點大于2{size = q.size();//在隊列里的節(jié)點,減去n -= size;//剩余的節(jié)點個數(shù)nwhile(size--){tp = q.front();//待刪除的節(jié)點q.pop();for(const int& id : g[tp]){g[id].erase(tp);if(g[id].size() == 1)//id變成最外層了q.push(id);//進入隊列,待刪}}}while(!q.empty()){vertex.push_back(q.front());q.pop();}return vertex;} };

總結(jié)

以上是生活随笔為你收集整理的LeetCode 310. 最小高度树(图 聪明的BFS,从外向内包围)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。