找树左下角的值
leetcode:513. 找树左下角的值
层序迭代法
思路
层序遍历,每次更新result
为每层最左侧元素。
复杂度分析
时间复杂度:遍历,O(N)。
空间复杂度:队列层序遍历,树*似完全二叉树时O(N),树极倾斜时O(logN)。
注意点
略
代码实现
/**
* 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:
// 层序迭代
// 1. 最底层;2. 最左边
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if(!root->left && !root->right) return root->val;
que.push(root);
int result = 0;
while(!que.empty()){
int size = que.size();
vector<int> vec;
while(size--){
TreeNode* node = que.front(); que.pop();
vec.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result = vec[0]; // 每层遍历结束更新为最左边值
}
// 层序遍历结束,到达最底层
return result;
}
};
递归法
思路
递归遍历,如果深度比历史最深还深则更新返回值result
。
- 终止条件:是叶子节点。且如果深度大于历史最深则更新
result
- 左右子树遍历。一定要先左后右!配合上面的深度严格大于历史最深更新,result每次更新为该层最左侧的元素。
复杂度分析
时间复杂度:O(N)。
空间复杂度:递归遍历,**衡时O(logN),极倾斜时O(N)。
注意点
略
代码实现
/**
* 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 result = INT32_MIN;
int maxDepth = 0;
void traversal(TreeNode* node,int depth){
// 叶子节点返回
if(!node->left && !node->right){
// 如果是新的一层则更新result
if(depth > maxDepth){
maxDepth = depth;
result = node->val;
}
}
if(node->left) traversal(node->left,depth + 1);
if(node->right) traversal(node->right,depth + 1);
}
int findBottomLeftValue(TreeNode* root) {
if(!root->left && !root->right) return root->val;
else traversal(root,1);
return result;
}
};
路径总和
leetcode:
前序递归遍历法
思路
基于257. 二叉树的所有路径,遍历过程中,每次碰到叶子节点时进行结算比较,如果符合值,标志isFound = true
,递归返回。
复杂度分析
时间复杂度:O(N)
空间复杂度:递归遍历,层数越多,递归越深,栈占用越多,*完全时O(logN),极倾斜时O(N)。
注意点
- 只在叶子节点时进行比较、结果的更新
- 可以不通过对比的方式,通过初始化
count = targetSum
,然后再递减node->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 isFound = false;
void traversal(TreeNode* node,int pathSum,int targetSum){
// 找到对应值终止
if(isFound) return;
pathSum += node->val; // 中
// 叶子节点也终止,且进行走完路径的结算比较!
if(!node->left && !node->right){
if(pathSum == targetSum) isFound = true;
return;
}
if(node->left) traversal(node->left,pathSum,targetSum);
if(node->right) traversal(node->right,pathSum,targetSum);
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == NULL) return false;
else traversal(root,0,targetSum);
return isFound;
}
};
路经总和Ⅱ:
/**
* 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;
void traversal(TreeNode* node,vector<int> path,int pathSum,int targetSum){
path.push_back(node->val);
pathSum += node->val;
if(!node->left && !node->right){
if(pathSum == targetSum) result.push_back(path);
return;
}
if(node->left) traversal(node->left,path,pathSum,targetSum);
if(node->right) traversal(node->right,path,pathSum,targetSum);
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> path;
if(root == NULL) return result;
traversal(root,path,0,targetSum);
return result;
}
};
从中序和后序遍历构造二叉树
leetcode:106. 从中序与后序遍历序列构造二叉树
递归法
思路
六脉神剑
- 如果数组为空,返回NULL;
- 取后序数组末元素为根节点的值;
- 找到根节点在中序数组位置的
index
; - 划分中序数组
inLeft
、inRight
; - 根据中序划分结果划分后序数组
postLeft
、postRight
; - 递归构造左右节点。
复杂度分析
时间复杂度:O(NH)。每次递归都要遍历部分中序数组,总体完整遍历了中序数组。递归深度H取决于树的形态,若*衡则为O(NlogN),若不*衡则O(N^2)。
空间复杂度:O(N),递归栈的深度。但是由于每次递归都创建了新vector
,占用空间比较多,时间也比较慢。
注意点
-
root
是TreeNode*
类型,不能用TreeNode
类型的构造函数。(
TreeNode* root = new TreeNode(postorder[postorder.size() - 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* traversal(vector<int>& inorder,vector<int>& postorder){
// 第一步
if(postorder.size() == 0) return NULL;
// 第二步,取根节点
TreeNode* root = new TreeNode(postorder[postorder.size() - 1]);
// 第三步,找到根节点在中序数组的位置
int i = 0;
for(;i < inorder.size();i++){
if(root->val == inorder[i]) break;
}
// 第四步,先划分中序
// 左闭右开
vector<int> inLeft(inorder.begin(),inorder.begin() + i);
vector<int> inRight(inorder.begin() + i + 1,inorder.end());
// 第五步,再划分后序
vector<int> postLeft(postorder.begin(),postorder.begin() + inLeft.size());
vector<int> postRight(postorder.begin() + inLeft.size(),postorder.end() - 1);
// 第六步,递归构造左右节点
root->left = traversal(inLeft,postLeft);
root->right = traversal(inRight,postRight);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return traversal(inorder,postorder);
}
};
标签:node,right,TreeNode,val,int,18,二叉树,左下角,left
From: https://www.cnblogs.com/tazdingo/p/18016758