LeetCode513.找树左下角的值
题目链接:513. 找树左下角的值 - 力扣(LeetCode)
思路:
迭代法(只需要记录最后一行第一个节点的数值就可以了。):
/**
* 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;
int result = 0;
if(root == NULL) return 0;
que.push(root);
//迭代法每次双重循环都将每层的节点数等于size,然后遍历
while(!que.empty()) {
int size = que.size();
for(int i = 0;i < size;i++) {
TreeNode* node = que.front();
que.pop();
if(i == 0) result = node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return result;
}
};
递归(深度最大的叶子节点一定是最后一行):
/**
* 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 travel(TreeNode* root,int depth) {
if(root->left == NULL && root->right == NULL) {
if(depth > maxdepth) {
maxdepth = depth;
result = root->val;
}
return;
}
if(root->left) {
depth++;
travel(root->left,depth);
depth--;
}
if(root->right) {
depth++;
travel(root->right,depth);
depth--;
}
return;
}
int findBottomLeftValue(TreeNode* root) {
travel(root,0);
return result;
}
};
LeetCode112.路经总和
思路:
返不返回函数值
如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。
如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。
如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。
/**
* 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 travel(TreeNode* cur,int count) {
if(!cur->left && !cur->right && count == 0) return true;//遇到叶子节点并且计数=0
if(!cur->left && !cur->right) return false;//遇到叶子节点直接返回
if(cur->left) {//左
count -= cur->left->val;//递归,处理节点
if(travel(cur->left,count)) return true;
count += cur->left->val;//回溯,撤销处理结果
}
if(cur->right) {//右
count -= cur->right->val;//递归,处理节点
if(travel(cur->right,count)) return true;
count += cur->right->val;//回溯,撤销处理结果
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
return travel(root,targetSum - root->val);
}
};
迭代:
/**
* 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 == NULL) 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();
//如果该节点是叶子节点 ,同时路径之和等于给定值,返回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;
}
};
LeetCode113.路经总和II
题目链接:113. 路径总和 II - 力扣(LeetCode)
思路:clear函数不是删除空间,而是将字首设为‘/0’
/**
* 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 travel(TreeNode* cur,int count) {
if(!cur->left && !cur->right && count == 0) {
//遇到叶子节点且找到了和为sum的路径
result.push_back(path);
return;
}
if(!cur->left && !cur->right) return;//遇到叶子节点而没找到合适的边,直接返回
if(cur->left) {//左(空节点不遍历)
path.push_back(cur->left->val);
count -= cur->left->val;
travel(cur->left,count);//递归
count += cur->left->val;//回溯
path.pop_back();//回溯
}
if(cur->right) {
path.push_back(cur->right->val);
count -= cur->right->val;
travel(cur->right,count);//递归
count += cur->right->val;//回溯
path.pop_back();//回溯
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if(root == NULL) return result;
path.push_back(root->val);
travel(root,targetSum - root->val);
return result;
}
};
LeetCode106.从中序与后序遍历序列构造二叉树(此题记得多看)
题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
思路:
中,后序构造唯一二叉树:
以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。
-
第一步:如果数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
-
第五步:切割后序数组,切成后序左数组和后序右数组
-
第六步:递归处理左区间和右区间
/**
* 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* travel(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 delimiterIndex;
for(delimiterIndex = 0;delimiterIndex < inorder.size();delimiterIndex++) {
if(inorder[delimiterIndex] == rootvalue) break;
}
//切割中序数组
//左闭右开区间 [0,delimiterIndex)
vector<int> leftinorder(inorder.begin(),inorder.begin() + delimiterIndex);
//[delimiterIndex + 1,end)
vector<int> rightinorder(inorder.begin() + delimiterIndex + 1,inorder.end());
//postorder舍弃末尾元素
postorder.resize(postorder.size() - 1);
//切割后序数组
//左闭右开,使用了左中序数组大小作为切割点
//[0,leftinorder.size())
vector<int> leftpostorder(postorder.begin(),postorder.begin() + leftinorder.size());
//[leftinorder.size(),postoreder.end())
vector<int> rightpostorder(postorder.begin() + leftinorder.size(),postorder.end());
root->left = travel(leftinorder,leftpostorder);
root->right = travel(rightinorder,rightpostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size() == 0 || postorder.size() == 0) return NULL;
return travel(inorder,postorder);
}
};