找树左下角的值
1.递归(找到第一个深度最大的叶子结点,返回其值)
/**
* 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=0;
void traversal(TreeNode* root,int deep){
if(root->left==NULL&&root->right==NULL){//递归终止条件
if(deep>maxDepth){
maxDepth=deep;
result=root->val;
}
return;
}
if(root->left) traversal(root->left,deep+1);//隐藏着回溯
if(root->right) traversal(root->right,deep+1);
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,1);//传入初始参数
return result;
}
};
2.迭代,层序遍历(找到最后一层第一个结点,返回其值)
/**
* 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 findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
vector<int> result;
while(!que.empty()){
int size=que.size();
result.push_back(que.front()->val);//把每一层的第一个结点的值加入数组
for(int i=0;i<size;i++){
TreeNode* cur=que.front();
que.pop();
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
}
return result[result.size()-1];//数组末尾元素就是最后一层第一个元素
}
};
路径总和
1.递归(注意递归函数的返回类型,不同的返回类型需要不同的处理方式)
/**
* 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* cur,vector<int> &path,int &targetSum){
path.push_back(cur->val);
if(cur->left==NULL&&cur->right==NULL){
int sum=0;
for(int i=0;i<path.size();i++){//计算路径之和
sum+=path[i];
}
if(sum==targetSum) return true;
}
if(cur->left){
if(traversal(cur->left,path,targetSum)) return true;
path.pop_back();//回溯
}
if(cur->right){
if(traversal(cur->right,path,targetSum)) return true;
path.pop_back();//回溯
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL) return false;
vector<int> path;
return traversal(root,path,targetSum);
}
};
2.递归法精简版(注意回溯的实现)
/**
* 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 hasPathSum(TreeNode* root, int targetSum) {
if(root==nullptr) return false;
if(!root->left&&!root->right&&root->val==targetSum)
return true;
return hasPathSum(root->left,targetSum-root->val)||
hasPathSum(root->right,targetSum-root->val);
}
};
3.迭代法,前序遍历版(创建一个栈结构,栈内元素包含当前结点以及当前结点的路径之和,按前序遍历顺序出栈依次判断路径之和是否等于目标值)
/**
* 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 hasPathSum(TreeNode* root, int targetSum) {
if (root == nullptr) return false;
// 此时栈里要放的是pair<节点指针,路径数值>
stack<pair<TreeNode*, int>> st;
st.push(pair<TreeNode*, int>(root, root->val));
while (!st.empty()) {
pair<TreeNode*, int> node = st.top();
st.pop();
// 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
if (!node.first->left && !node.first->right && targetSum == node.second)
return true;
// 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if (node.first->right) {
st.push(pair<TreeNode*, int>(node.first->right,
node.second + node.first->right->val));
}
// 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if (node.first->left) {
st.push(pair<TreeNode*, int>(node.first->left,
node.second + node.first->left->val));
}
}
return false;
}
};
1.递归(注意路径不止一条,要想把递归中获得的路径全部加入,最好设置一个全局变量接收返回路径)
/**
* 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://递归法
vector<vector<int>> result;//全局变量
vector<int> path;//全局变量
void traversal(TreeNode* cur,int &targetSum){
path.push_back(cur->val);
if(cur->left==NULL&&cur->right==NULL){
int sum=0;
for(int i=0;i<path.size();i++){//计算路径之和
sum+=path[i];
}
if(sum==targetSum) result.push_back(path);
}
if(cur->left){
traversal(cur->left,targetSum);
path.pop_back();//回溯
}
if(cur->right){
traversal(cur->right,targetSum);
path.pop_back();//回溯
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(root==NULL) return result;//空节点没有路径
traversal(root,targetSum);
return result;
}
};
2.迭代法(暂时还不会……)
从中序与后序遍历序列构造二叉树
1.递归法(主要是数组的划分切割)
/**
* 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* buildTree(vector<int>& inorder, vector<int>& postorder) {
//中序、后序遍历数组相同,判断一个就行
if(postorder.size()==0) return NULL;
//不空则后序遍历最后一个为根节点,创建一个要返回的根节点接收
int rootValue=postorder[postorder.size()-1];
TreeNode* root=new TreeNode(rootValue);
//根节点同时为叶子结点,直接返回
if(postorder.size()==1) return root;
int i;
//找出根节点在中序遍历数组里面的下标进行切割
for(i=0;i<inorder.size();i++){
if(inorder[i]==rootValue)
break;
}
//以根节点下标为界切割中序数组(左闭右开根节点不在其中)
vector<int> leftInorder(inorder.begin(),inorder.begin()+i);
vector<int> rightInorder(inorder.begin()+i+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=buildTree(leftInorder,leftPostorder);
root->right=buildTree(rightInorder,rightPostorder);
//返回根节点
return root;
}
};
2.迭代法(暂时战略性放弃……)
1.递归法(还是划分数组)
/**
* 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
//中序、前序遍历数组相同,判断一个就行
if(preorder.size()==0) return NULL;
//不空则前序遍历第一个为根节点,创建一个要返回的根节点接收
int rootValue=preorder[0];
TreeNode* root=new TreeNode(rootValue);
//根节点同时为叶子结点,直接返回
if(preorder.size()==1) return root;
int i;
//找出根节点在中序遍历数组里面的下标进行切割
for(i=0;i<inorder.size();i++){
if(inorder[i]==rootValue)
break;
}
//以根节点下标为界切割中序数组(左闭右开根节点不在其中)
vector<int> leftInorder(inorder.begin(),inorder.begin()+i);
vector<int> rightInorder(inorder.begin()+i+1,inorder.end());
//前序遍历第一个结点已经加入故抛弃
preorder.erase(preorder.begin());
//把剩余前序遍历数组切割成对应的两部分
vector<int> leftPreorder(preorder.begin(),preorder.begin()+leftInorder.size());
vector<int> rightPreorder(preorder.begin()+leftInorder.size(),preorder.end());
//递归切割好的左右中序前序数组
root->left=buildTree(leftPreorder,leftInorder);
root->right=buildTree(rightPreorder,rightInorder);
//返回根节点
return root;
}
};
2.迭代法(战略性放弃……)
今日总结:递归大法好啊。