給定一顆二叉樹,和兩個給定的結點,求出這兩個結點之間的距離
拿到題目時不要認為是求出二叉樹的結點之間的最大距離,題目是求兩個結點的之間的距離
題目有幾種情況
- 兩個結點分佈在根節點的左子樹或者右子樹
- 一個結點分佈在根節點的左子樹,一個結點分佈在根節點的右子樹
- 這兩個結點是兄弟結點
- 一個結點是另外結點的祖先結點
本題的解題思路是
利用層次遍歷的方法,獲取每個結點的高度,根節點左子樹的高度用正數表示,根節點右子樹的高度用負數表示
這樣當兩個結點分佈在:一個結點分佈在根節點的左子樹,一個結點分佈在根節點的右子樹時,只需要兩個結點的高度的差得絕對值即可
如果一個結點是另一個結點的祖先結點,只需要高度大的結點順著祖先結點找到高度小得結點,如果到達相同的高度結點不相同說明是兄弟結點關係
#include <iostream> #include <vector> #include <queue> #include <stack> #include <string> #include <algorithm> using namespace std; struct TreeNode{ int val; TreeNode* left; TreeNode* right; TreeNode(int val_ = 0):val(val_),left(NULL),right(NULL){} }; struct TreeHeightNode{ int height; TreeNode* node; TreeHeightNode* parent; TreeHeightNode(TreeNode* node_ = NULL,int height_ = 0,TreeHeightNode* parent_ =NULL): node(node_), height(height_),parent(parent_){} }; int getDistanceBetweenNode(TreeNode* root,TreeNode* a, TreeNode* b){ if(root == NULL ) return -1; queue<TreeHeightNode *> que; que.push(new TreeHeightNode(root,0)); bool flagA = false, flagB = false; // int heightA = 0, heightB = 0; TreeHeightNode* heightA =NULL, *heightB = NULL; while(!que.empty()){ TreeHeightNode* tmp = que.front(); que.pop(); TreeNode *node = tmp->node; if(node == a) {flagA = true;heightA = tmp;} if(node == b) {flagB = true;heightB = tmp;} if(flagA && flagB) break; if(node->left){ if(node->val == 0) que.push(new TreeHeightNode(node->left,1,tmp)); else if(node->val > 0) que.push(new TreeHeightNode(node->left,tmp->height+1,tmp)); else if(node->val < 0) que.push(new TreeHeightNode(node->left,tmp->height-1,tmp)); } if(node->right){ if(node->val == 0) que.push(new TreeHeightNode(node->right,-1,tmp)); else if(node->val > 0) que.push(new TreeHeightNode(node->right,tmp->height+1,tmp)); else if(node->val < 0) que.push(new TreeHeightNode(node->right,tmp->height-1,tmp)); } } if(!flagA || !flagB) return -1; else{ int ha = heightA->height, hb =heightB->height; if(ha*hb <=0) return ha-hb; else{ if((ha >= hb && hb > 0) || (ha < hb && hb < 0)){ int cnt = ha-hb; while(cnt-->0){ heightA=heightA->parent; } if(heightA == heightB) return ha-hb; else return ha-hb+2; }else{ int cnt = hb - ha; while(cnt-- > 0){ heightB=heightB->parent; } if(heightB == heightA) return hb-ha; else return hb-ha+2; } } } } int main(){ TreeNode *root = new TreeNode(1); TreeNode *left = new TreeNode(2); TreeNode *right = new TreeNode(3); root->left = left; root->right = right; TreeNode *left1 = new TreeNode(4); TreeNode *right1 = new TreeNode(5); left->left = left1; left->right = right1; TreeNode *left2 = new TreeNode(4); TreeNode *right2 = new TreeNode(5); left1->left = left2; left1->right = right2; cout<<getDistanceBetweenNode(root,left2,right)<<endl; return 0; }
其實尋找兩個結點的距離就是求兩個結點的公共祖先結點,所以另一種方法是找到o最小其公共祖先結點
然後