二叉树路径

题目描述

   有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
   给定二叉树的根节点root,请返回所求距离。

解题思路

   基本想法:首先遍历二叉树,找到最大最小叶节点的位置,然后找到两者的最小公共祖先(这里的最小祖先指的是位置最靠近两个节点的祖先)。
   方法一:找到最大最小叶节点的位置需要遍历整个二叉树,寻找公共祖先可以从其中一个节点开始,向上追溯,并且标记访问过的节点,另一个节点在向上追溯的过程中,遇到被访问过的节点就可以停止,两个节点到达这一节点的步数和就是距离长度。
   方法二:在寻找最大最小叶节点的时候同时记录其路径,然后比较两条路径,去掉公共部分,剩下的就是两个节点的距离。

代码实现

方法一:

#include <iostream>
#include <vector>
#include <limits>
using namespace std;
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};

class Tree {
public:	
    int getDis(TreeNode* root) {
        // write code here
	    vector<int> indexs;
        vector<int> weights;
		int maxn_index,minn_index;
		Traverse(root,indexs,weights,maxn_index,minn_index);
		int distance=getDisByIndex(maxn_index,minn_index,indexs);
		return distance;
    }
	void Traverse(TreeNode* root,vector<int>& indexs,vector<int>& weights,int& maxn_index,int& minn_index){
		if(root==NULL) return;
		vector<TreeNode*> nodes;
		maxn_index=-1;
		minn_index=-1;
		int minn = numeric_limits<int>::max();
        int maxn = numeric_limits<int>::min();
        nodes.push_back(root);
		indexs.push_back(-1);
		weights.push_back(root->val);
		TreeNode *left,*right,*current;
		int i=-1;
		while(!nodes.empty()){
			current=nodes[0];
			nodes.erase(nodes.begin());
			i++;
			left=current->left;
			right=current->right;
			if(left==NULL && right==NULL){			
				if(minn>current->val){
					minn=current->val;
					minn_index=i;
				}
				if(maxn<current->val){
					maxn=current->val;
					maxn_index=i;
				}
			}
			if(left!=NULL){
				nodes.push_back(left);
				indexs.push_back(i);
				weights.push_back(left->val);
			}
			if(right!=NULL){
				nodes.push_back(right);
				indexs.push_back(i);
				weights.push_back(right->val);
			}
		}


	}

	int getDisByIndex(int maxn_index,int minn_index,vector<int>& indexs){
		if(maxn_index==minn_index) return 0;
		vector<int> visit;
		int n=indexs.size();
		visit.resize(n,-1);
		int step=0;
		int pmax,pmin;
		pmax=maxn_index;
		while(pmax!=-1){
			if(visit[pmax]==-1){
				visit[pmax]=step++;
				pmax=indexs[pmax];
			}
		}
		int cnt=0;
		pmin=minn_index;
		while(pmin!=-1){
			if(visit[pmin]!=-1){
				return cnt+visit[pmin];
				}
			pmin=indexs[pmin];
			cnt++;
		}
	}
}

方法二:

#include <iostream>
#include <limits>
using namespace std;
struct TreeNode{
	int val;
	TreeNode *left,*right;
	TreeNode(int x):val(x),left(NULL),right(NULL){}
}
class Solution{
	public:
	int minn,maxn;
	vector<int> minn_path,maxn_path;
	int getDis(TreeNode* root){
	
		minn=limits<int>::max();
		maxn=limits<int>::min();
		vector<int> vec;
		dfs(root,vec);
		
		for(int i=0;;i++){
			if(minn_path[i]==maxn_path[i])
				continue;
			else
				return minn_path.size()-i+maxn_path.size();
		}
		
	}
	void dfs(TreeNode* root,vector<int>& vec){
		if(root==NULL)return;
		if(root->left==NULL && root->right==NULL){
			if(minn>root->val){
				minn=root->val;
				minn_path.assign(vec.begin(),vec.end());
			}
			if(maxn<root->val){
				maxn=root->val;
				maxn_path.assign(vec.begin(),vec.end());
			}
		}
		vec.push_back(-1);
		dfs(root->left,vec);
		vec.pop_back();
		
		vec.push_back(1);
		dfs(root->right,vec);
		vec.pop_back();
	}
}

   这道题的思路很清晰,理清楚就可以。但是笔者却花了半天时间,就是显示无法通过测试用例,我确信方法没问题,调试到怀疑人生。。。后来发现题目是最大最小叶节点,而我做的是最大最小节点!!!

发布了16 篇原创文章 · 获赞 0 · 访问量 346

猜你喜欢

转载自blog.csdn.net/qq_41922018/article/details/104225097