题目链接:513.找树左下角的值
递归三部曲:
确定递归函数的参数和返回值
参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。
代码如下:
int maxDepth = INT_MIN;
// 全局变量 记录最大深度
int result;
// 全局变量 最大深度最左节点的数值
voidtraversal(TreeNode* root,int depth)
确定终止条件
当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
代码如下:
if(root->left ==NULL&& root->right ==NULL)
{ if(depth > maxDepth)
{
maxDepth = depth;// 更新最大深度
result = root->val;// 最大深度最左面的数值
}
return;
}
确定单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯,代码如下:
if(root->left)
{
depth++;// 深度加一
traversal(root->left, depth);
depth--;// 回溯,深度减一
}
if(root->right)
{
depth++;// 深度加一
traversal(root->right, depth);
depth--;// 回溯,深度减一
}
return;
完整代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth=INT_MIN;
int result;
void traversal(TreeNode* root,int depth){
if(root->left==nullptr&&root->right==nullptr)
{
if(depth>maxDepth)
{
maxDepth=depth;
result=root->val;
}
return;
}
if(root->left)
{
depth++;
traversal(root->left,depth);
depth--;
}
if(root->right)
{
depth++;
traversal(root->right,depth);
depth--;
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
题目链接:112. 路径总和
这道题使用深度优先遍历:
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool traversal(TreeNode* root, int count)
{
if(!root->left&&!root->right&&count==0)
{
return true;
}
if(!root->left&&!root->right)
{
return false;
}
if(root->left)
{
count-=root->left->val;
if(traversal(root->left,count)) return true;
count+=root->left->val;
}
if(root->right)
{
count-=root->right->val;
if(traversal(root->right,count)) return true;
count+=root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==nullptr)
return false;
return traversal(root,targetSum-root->val);
}
};
题目链接:113.路径总和ii
路径总和ii要遍历整个树,找到所有路径,所以递归函数不要返回值!
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void traversal(TreeNode* root, int count)
{
if(!root->left&&!root->right&&count==0)
{
result.push_back(path);
return;
}
if(!root->left&&!root->right)
{
return;
}
if(root->left)
{
path.push_back(root->left->val);
count-=root->left->val;
traversal(root->left,count);
count+=root->left->val;
path.pop_back();
}
if(root->right)
{
path.push_back(root->right->val);
count-=root->right->val;
traversal(root->right,count);
count+=root->right->val;
path.pop_back();
}
return;
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if(root==nullptr) return result;
path.push_back(root->val);
traversal(root,targetSum-root->val);
return result;
}
};
题目链接:106.从中序与后序遍历序列构造二叉树
说到一层一层切割,就应该想到了递归。
第一步:如果数组大小为零的话,说明是空节点了。
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
第五步:切割后序数组,切成后序左数组和后序右数组
第六步:递归处理左区间和右区间
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder)
{
if(postorder.size()==0)
return nullptr;
int rootValue=postorder[postorder.size()-1];
TreeNode *root=new TreeNode(rootValue);
if(postorder.size()==1) return root;
int definitIndex;
for(definitIndex=0;definitIndex<inorder.size();definitIndex++)
{
if(inorder[definitIndex]==rootValue) break;
}
//vector<int> leftInorder(inorder.begin(), inorder.begin() + definitIndex);
vector<int> leftInorder(inorder.begin(),inorder.begin()+definitIndex);
vector<int> rightInorder(inorder.begin()+definitIndex+1,inorder.end());
postorder.resize(postorder.size()-1);
vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());
root->left=traversal(leftInorder,leftPostorder);
root->right=traversal(rightInorder,rightPostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0)
return nullptr;
return traversal(inorder,postorder);
}
};
题目链接:105.从前序与中序遍历序列构造二叉树
本题和106是一样的道理
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
TreeNode* traversal(vector<int>& preorder, int preBegin,int preEnd,vector<int>& inorder,int inBegin,int inEnd)
{
if(preEnd==preBegin) return nullptr;
int rootValue=preorder[preBegin];
TreeNode *root=new TreeNode(rootValue);
if(preEnd-preBegin==1) return root;
int definitIndex;
for(definitIndex=inBegin;definitIndex<inEnd;definitIndex++)
{
if(inorder[definitIndex]==rootValue) break;
}
int leftInorderBegin=inBegin;
int leftInorderEnd=definitIndex;
int rightInorderBegin=definitIndex+1;
int rightInorderEnd=inEnd;
int leftPreorderBegin=preBegin+1;
int leftPreorderEnd=preBegin+1+definitIndex-inBegin;
int rightPreorderBegin=preBegin+1+definitIndex-inBegin;
int rightPreorderEnd=preEnd;
root->left=traversal(preorder,leftPreorderBegin,leftPreorderEnd,inorder,leftInorderBegin,leftInorderEnd);
root->right=traversal(preorder,rightPreorderBegin,rightPreorderEnd,inorder,rightInorderBegin,rightInorderEnd);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
if(preorder.size()==0||inorder.size()==0) return nullptr;
return traversal(preorder,0,preorder.size(),inorder,0,inorder.size());
}
};