树的直径
树的直径
https://leetcode.cn/problems/tree-diameter/
class Solution { public: int treeDiameter(vector<vector<int>>& edges) { n = 0; for(vector<int>& edge : edges) { int x = edge[0]; int y = edge[1]; n = max(n, max(x, y)); } n++; for(int i = 0; i < n; i++) to.push_back({}); for(vector<int>& edge : edges) { int x = edge[0]; int y = edge[1]; to[x].push_back(y); to[y].push_back(x); } int p = findFarthest(0).first; return findFarthest(p).second; } private: vector<vector<int>> to; int n; pair<int, int> findFarthest(int start) { vector<int> depth(n, -1); queue<int> q; q.push(start); depth[start] = 0; while(!q.empty()) { int x = q.front(); q.pop(); for (int y : to[x]) { if (depth[y] != -1) continue; depth[y] = depth[x] + 1; q.push(y); } } int ans = start; for(int i = 0; i < n; i++) if(depth[i] > depth[ans]) ans = i; return {ans, depth[ans]}; } };
两次深度优先遍历
- 第一次从任意一个点出发,找到距离它最远的点p
- 第二次从p出发,找到距离它最远的点q
- 连接p,q的路径即为树的直径
最近公共祖先(LCA)
236.二叉树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/
先求出父结点,然后用向上标记法
- p向上一直到root标红色
- q向上,第一次遇到红色时,就找到了LCA
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { this->p=p; this->q=q; dfs(root); return ans; } private: TreeNode* ans; TreeNode* p; TreeNode* q; pair<bool,bool> dfs(TreeNode* root){ if(root==nullptr) return {false,false}; pair<bool,bool> leftResult = dfs(root->left); pair<bool,bool> rightResult = dfs(root->right); pair<bool,bool> result; result.first = leftResult.first || rightResult.first || root==p; result.second = leftResult.second || rightResult.second || root==q; if(result.first && result.second && ans==nullptr) ans=root; return result; } };
基环树
向一棵树添加一条边,就形成了一个环
此时整个结构被称为基环树( pseudotree / unicyclic graph)
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习