目录
二叉树中和为某一值的路径(三)
描述:给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum 。
1.该题路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点
2.总节点数目为n
3.保证最后返回的路径个数在整形范围内(即路径个数小于231-1)
数据范围:0<=n<=10000 −10^9<=节点值<=10^9
思路:通过两个dfs对每个结点进行深度遍历
class Solution {
public:
int res=0;//数量
void dfs(TreeNode* root,int sum){
if(!root) return;
if(sum==root->val)
res++;
dfs(root->left,sum-root->val);
dfs(root->right,sum-root->val);
}
int FindPath(TreeNode* root, int sum) {
if(!root) return res;
dfs(root,sum);
FindPath(root->left,sum);
FindPath(root->right,sum);
return res;
}
};
在二叉树中找到两个结点的最近父结点
描述:给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
数据范围:树上节点数满足 1≤n≤10^5 , 节点值val满足区间 [0,n)
要求:时间复杂度 O(n)
注:本题保证二叉树中每个节点的val值均不相同。
如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:
所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。
节点本身可以视为自己的祖先
思路:查询根结点到所求结点的路径,遍历查询两个路径节点值相同的最后一个结点。
class Solution {
public:
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
bool find=false;
void dfs(TreeNode* root,int o,vector<int>& a){
if(!root) return;
a.push_back(root->val);
if(root->val==o){
find=true;
return;
}
dfs(root->left,o,a);
dfs(root->right,o,a);
if(find) return;
a.pop_back();
}
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
vector<int> a1;
vector<int> a2;
int l1,l2,i;
dfs(root,o1,a1);
find=false;
dfs(root,o2,a2);
l1=a1.size();
l2=a2.size();
for(i=0;i<min(l1,l2)&&a1[i]==a2[i];i++);
i--;
return a1[i];
}
};
重点:在第一次书写该代码时,忽视了深度遍历时何时pop不是路径上的结点的问题。
此外,可以使用递归的方法解决。
思路:如果根结点值和两个结点值相同,则返回根结点;否则,如果两个结点在树上的话,只可能存在三种可能性:都在左子树,都在右子树,或一个在左子树,一个在右子树。
class Solution {
public:
TreeNode* dfs(TreeNode* root, int o1, int o2) {
if(root == nullptr) return nullptr; //超过叶节点,返回空
if(root->val == o1 || root->val == o2) return root; //节点为其中一个
TreeNode* t1 = dfs(root->left, o1, o2);
TreeNode* t2 = dfs(root->right, o1, o2);
if(t1 == nullptr) return t2; //此时两个节点都在右侧
if(t2 == nullptr) return t1; //此时两个节点都在左侧
return root; //此时两个节点分别位于左右两侧
}
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
return dfs(root, o1, o2)->val;
}
};
二叉搜索树的最近公共父结点
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
1.对于该题的最近的公共祖先定义:对于有根树T的两个节点p、q,最近公共祖先LCA(T,p,q)表示一个节点x,满足x是p和q的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先.
2.二叉搜索树是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值
3.所有节点的值都是唯一的。
4.p、q 为不同节点且均存在于给定的二叉搜索树中。
数据范围:
3<=节点总数<=10000
0<=节点值<=10000
思路:借鉴上个问题的递归方法,这个问题增加的是二叉搜索树的条件,即左孩子结点值<根结点值<右孩子节点值。
class Solution {
public:
TreeNode* dfs(TreeNode* root,int p,int q){
if(!root) return NULL;
if(root->val==p||root->val==q) return root;
int mint=min(p,q),maxt=max(p,q);
TreeNode* left=dfs(root->left,p,q);
TreeNode* right=dfs(root->right,p,q);
if(root->val>maxt) return left;
if(root->val<mint) return right;
return root;
}
int lowestCommonAncestor(TreeNode* root, int p, int q) {
return dfs(root,p,q)->val;
}
};