IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【LeetCode 310】 310. Minimum Height Trees题解(记忆化搜索) -> 正文阅读

[数据结构与算法]【LeetCode 310】 310. Minimum Height Trees题解(记忆化搜索)

【LeetCode 310】 310. Minimum Height Trees题解(记忆化搜索)

题目

一棵树以任意一结点为根都可以形成一棵树,找出形成树高度最小的所有根节点。看似 O ( n 2 ) O(n^2) O(n2)能过,实际上过不了,得考虑 O ( n ? log ? n O(n\cdot \log{n} O(n?logn或者 O ( n ) O(n) O(n)的思路。

解题思路

  1. 假设以结点 x x x为根, x x x i ? ? ? j i···j i???j若干子结点,若干子节点为根形成的树高度依次为 H i ? ? ? H j H_i···H_j Hi????Hj?
  2. 则以 x x x为根的树的高度为所有子节点最大高度+1= m a x ( H i , ? ? ? , H j ) + 1 max(H_i,···,H_j)+1 max(Hi?,???,Hj?)+1
  3. 对于任何一个结点,其子节点方向一旦搜索过则可以直接获取存储的高度而不用再次搜索。(记忆化搜索)
  4. 所以达到任何一个结点能够 O ( 1 ) O(1) O(1)获取到其所有子节点的高度,即计算出任何一个结点为根的高度,只需要每条边双向都遍历一遍,遍历次数为 2 ? n 2\cdot n 2?n,时间复杂度为 O ( n ) O(n) O(n)
    遍历过程

Code

class Solution {
public:       
    // 已经计算过的根节点的树的最小高度。
    int minHeight = INT_MAX;
    // 记录以其为根使树高度最小的结点。
    vector<int> ans;
    // dfs深度优先搜索。
    // v[i][j].first表示结点i的第j个子结点,v[i][j].second表示结点i到结点v[i][j]方向的深(高)度。
    // visit标识当前轮是否访问过某结点。
    int dfs(int n, vector<pair<int,int>> v[], int pre, bool* visit){
    	// 访问过,将当前结点pre的visit设置为true
        visit[pre] = true;
        // 度为1的树高度为1
        int height = 1;
        for(int i = 0;i < v[pre].size(); ++i){
        	// nxt=与pre邻接的第i个结点的值
            int nxt = v[pre][i].first;
            // 如果pre->nxt方向没访问过,且nxt结点没访问过,则访问nxt结点
            if(v[pre][i].second == INT_MAX and !visit[nxt]){
                v[pre][i].second = dfs(n,v,nxt,visit)+1;
                height = max(height,v[pre][i].second);
            // 如果pre->nxt方向访问过,但是当前轮nxt结点没访问过,则从nxt方向获取其最大高度(排除nxt->pre方向)
            }else if(!visit[nxt]){
                for(int j = 0;j < v[nxt].size(); ++j){
                    if(v[nxt][j].first != pre){
                        v[pre][i].second = max(v[pre][i].second,v[nxt][j].second+1);
                        height = max(height,v[pre][i].second);
                    }
                }
                // 如果nxt结点度为1,即只有nxt->pre方向,则将pre->nxt方向深度记为2
                if(v[nxt].size() == 1){
                    v[pre][i].second = 2;
                    height = max(height,v[pre][i].second);
                }
               	// 如果当前结点为根的高度已经大于已经计算过的根节点的高度,则不用继续访问
                if(ans.size() > 0 and height > minHeight) return height;
            }
            // 如果当前结点pre为根的高度已经大于已经计算过的根节点的高度,则不用继续访问
            if(ans.size() > 0 and height > minHeight) return height;
        }
        // 根据pre邻接的所有方向的高度,返回pre为根节点的最大高度(排除prepre->pre方向,其中prepre为dfs的上一层递归函数的pre)
        return height;
    }
    
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
    	// 构造邻接表,v[i][j].first表示结点i的第j个子结点,v[i][j].second表示结点i到结点v[i][j]方向的深(高)度。
        vector<pair<int,int>> v[n];
        for(auto x:edges){
            v[x[0]].push_back({x[1],INT_MAX});
            v[x[1]].push_back({x[0],INT_MAX});
        }
        
        bool visit[n];
        for(int i = 0;i < n; ++i){
            memset(visit,false,sizeof(visit));
            int x = dfs(n,v,i,visit);
            // 如果以结点i为根的高度等于最小高度,则将i也加入答案;如果以结点i为根的高度小于最小高度,则清空答案,将i加入答案,最小高度置为结点i为根的高度。
            if(x == minHeight){
                ans.push_back(i);
            }else if(x < minHeight) {
                ans.clear();
                ans.push_back(i);
                minHeight = x;
            }
        }
        
        return ans;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 01:12:58  更:2022-09-30 01:17:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:45:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码