654 最大二叉树
递归思路:
参数应该是输入数组,返回值是一个节点
遍历找到数组最大值的下标,然后new一个根节点出来,左右子是递归送进去的该数组的左右下标。
终止条件就是传入数组为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:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
int n=nums.size();
if(n==0) return nullptr;
int root_value=nums[0],index=0;
for(int i=0;i<n;++i){
index= root_value>nums[i] ? index :i;
root_value=max(root_value,nums[i]);
}
TreeNode* head=new TreeNode(root_value);
if(index==0){
vector<int> L;
head->left=constructMaximumBinaryTree(L);
}
else{
vector<int> L(nums.begin(),nums.begin()+index);
head->left=constructMaximumBinaryTree(L);
}
if(index==n-1){
vector<int> R;
head->right=constructMaximumBinaryTree(R);
}
else{
vector<int> R(nums.begin()+index+1,nums.end());
head->right=constructMaximumBinaryTree(R);
}
return head;
}
};
AC
617 合并二叉树
感觉可以两个都层序遍历,然后null也算节点.
但这样无法根据队列是否为空来判断遍历是否结束。需要设置一个其他的标志位。
这样试了一下发现不行,层序遍历无法按层来新构建一个二叉树或者在原始二叉树上直接覆盖。因为创建节点(除非是根节点)需要跟他的父节点相连,但层序遍历只在本层循环,无法得到上一层的信息。
换递归。
递归的话感觉需要前序遍历才能从头节点开始构造。
前序遍历:头左右
两个二叉树各自开始前序遍历,但前序遍历的递归是遇到空节点就返回,这里如果有树遇到空节点直接返回,可能会直接错过新的节点的构造。(比如A树中有一个节点为空,B树这里对应的节点不为空,A树递归到这个空节点直接返回,那就错过这个在合并后的树上构造新节点的过程了)
暂时想不出来。。。看题解
看了第一行,题解思路是同时遍历两个树,然后再构建新的树,只要遍历过程中有一个节点不为空就可以继续遍历。试着写一下.
掰扯不明白,继续看题解。。。
完全明白了,前面想得太复杂了,其实这题的题解非常的简单。不需要新构造一棵树,因为还要从头节点开始,每个节点都要与其孩子链接很麻烦。直接在第一棵(或者第二棵)树上递归的时候顺便构造。
/**
* 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* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==nullptr) return root2;
if(root2==nullptr) return root1;
root1->val +=root2->val;
root1->left=mergeTrees(root1->left,root2->left);
root1->right=mergeTrees(root1->right,root2->right);
return root1;
}
};
700.二叉搜索树中的搜索
用层序遍历解出来了,但我感觉不是这样解的
/**
* 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* searchBST(TreeNode* root, int val) {
if(root==nullptr) return root;
queue<TreeNode*> myque;
myque.push(root);
while(myque.empty()==0){
int size=myque.size();
while(size--){
TreeNode* t=myque.front();
myque.pop();
if(t->val==val) return t;
if(t->left) myque.push(t->left);
if(t->right) myque.push(t->right);
}
}
return nullptr;
}
};
二叉搜索树是一个有序树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。
“
看看二叉搜索树的单层递归逻辑有何不同。
因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。
”
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr || root->val==val) return root;
if(root->val > val) return searchBST(root->left,val);
if(root->val < val) return searchBST(root->right,val);
return nullptr;
}
};
主要是用来学习如何利用二叉搜索树的性质的,递归不是问题。
迭代法:
一提到二叉树遍历的迭代法,可能立刻想起使用栈来模拟深度遍历,使用队列来模拟广度遍历。
对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。
对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。
而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
TreeNode* curr=root;
while(curr!=nullptr){
if(curr->val==val) return curr;
if(curr->val >val) curr=curr->left;
else if(curr->val <val) curr=curr->right;
}
return nullptr;
}
};
迭代法也AC
98.验证二叉搜索树
注意,节点相等的情况也构不成二叉树
/**
* 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 isValidBST(TreeNode* root) {
vector<int> num;
process(root,num);
int n=num.size();
for(int i=1;i<n;++i){
if(num[i-1]>=num[i]) return false;
}
return true;
}
void process(TreeNode* root, vector<int>& num){
if(root==nullptr) return;
process(root->left,num);
num.push_back(root->val);
process(root->right,num);
}
};
首先是递归,将该搜索树按中序遍历存成一个数组,那么数组就应该是从大到小排序的,然后遍历这个数组。如果出现不规律的排序,就返回false。
DAY22结束