654.最大二叉树
思路一:切割数组,生成新的左右数组
思路二:使用指针直接操作
class Solution {
public:
TreeNode*judge(vector<int>&nums,int left,int right){
if(left>=right) return nullptr;
//分割点下标
int maxNum=nums[left],index=left;//maxNum初始值为区间最左边的数
for(int i=left+1;i<right;i++){//获取最大值和下标
if(nums[i]>maxNum){
maxNum=nums[i];
index=i;
}
}
//cout<<index;
TreeNode*root=new TreeNode(maxNum);
//切割左子树和右子树
// vector<int> leftNums(nums.begin(),nums.begin()+index);
// vector<int> rightNums(nums.begin()+index+1,nums.end());
root->left=judge(nums,left,index);
root->right=judge(nums,index+1,right);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//思路二:不进行切割,直接在原数组上进行操作
return judge(nums,0,nums.size());
}
};
二刷:
思路一:切割数组
class Solution {
public:
TreeNode*containTree(vector<int>&nums){
if(nums.size()==0) return nullptr;
int maxValue=0,maxIndex=0;
for(int i=0;i<nums.size();i++){
if(nums[i]>maxValue){
maxValue=nums[i];
maxIndex=i;
}
}
TreeNode*root=new TreeNode(maxValue);
vector<int>leftnums(nums.begin(),nums.begin()+maxIndex);
vector<int>rightnums(nums.begin()+maxIndex+1,nums.end());
root->left=containTree(leftnums);
root->right=containTree(rightnums);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return containTree(nums);
}
};
思路二:双指针操作
class Solution {
public:
TreeNode*containsTree(vector<int>&nums,int left,int right){
if(left>=right) return nullptr;
int maxValue=nums[left],maxIndex=left;//因为存在 0 值,所以初始化为最左边的数
for(int i=left+1;i<right;i++){ //可以避免只有0值的情况导致 maxIndxe 为0
if(nums[i]>maxValue){
maxValue=nums[i];
maxIndex=i;
}
}
TreeNode*root=new TreeNode(maxValue);
root->left=containsTree(nums,left,maxIndex);
root->right=containsTree(nums,maxIndex+1,right);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return containsTree(nums,0,nums.size());
}
};
617.合并二叉树
思路一:创建新的二叉树
思路二:直接在二叉树上操作
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.二叉树中的搜索
思路:利用二叉搜索树的特性
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
//思路:找到节点,然后返回
//分析:左子节点比父节点小,右子节点比父节点大
if(root==nullptr)
return root;
TreeNode*newNode=root;;
if(newNode->val>val)
newNode=searchBST(newNode->left,val);
else if(newNode->val<val)
newNode=searchBST(newNode->right,val);
return newNode;
}
};
二刷:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr) return nullptr;
else if(root->val==val) return root;
else if(root->val>val) return searchBST(root->left,val);
return searchBST(root->right,val);
}
};
98.验证二叉搜索树
思路一:利用二叉搜索树的特性,中序遍历的数组必为升序
class Solution {
public:
vector<int>ans;
void judge(TreeNode*root){
if(root==nullptr) return;
judge(root->left);
ans.push_back(root->val);
judge(root->right);
}
bool isValidBST(TreeNode* root) {
//思路:直接分析
//思路二:中序遍历的数组一定递增
judge(root);
if(ans.size()==1) return true;
int pre=ans[0];
for(int i=1;i<ans.size();i++){
if(ans[i]<=pre)
return false;
pre=ans[i];
}
return true;
}
};
思路二:在递归的过程中直接判断,采用中序遍历,每次都记录上一个节点,然后判断当前节点是否大于上一个节点
class Solution {
public:
TreeNode*pre=nullptr;
bool isValidBST(TreeNode* root) {
if(root==nullptr) return true;//空树也是二叉搜索树
bool left=isValidBST(root->left);
if(pre!=nullptr && pre->val>=root->val) return false;//判断上一个节点是否小于当前节点
pre=root;
bool right=isValidBST(root->right);
return left && right;
}
};
二刷:
class Solution {
public:
vector<int>mid;
int count=0;//计数
void judge(TreeNode*root){//中序遍历
if(root==nullptr) return;
judge(root->left);
count++;
if(mid.empty() || root->val>mid.back()) mid.push_back(root->val);//递增时才加入
judge(root->right);
}
bool isValidBST(TreeNode* root) {//中序遍历必然是递增序列
judge(root);
return mid.size()==count;
}
};
669.修剪二叉搜索树
分析:分情况讨论,伪代码实现成代码,嗖嗖的
思路一:分析三种情况
1.当前节点值在中间区间上(此时递归分析左右子节点)
2.当前节点值在区间左边(此时当前节点不作为结果值,但右子节点中可能存在结果值,故返回分析右子节点)
3.当前节点值在区间右边(同理,当前节点不作为结果值,但左子节点可能存在结果值,故返回分析左子节点)
注意:判断当前节点为空时返回nullptr,可以解决叶子节点问题,也可以解决当前节点等于row或者等于high的问题。
class Solution {
public:
TreeNode*judgeNode(TreeNode*root,int low,int high){
if(root==nullptr) return root;
//分五种情况
TreeNode*left,*right;
if(root->val<low)//左边的必然不在区间内
return judgeNode(root->right,low,high);
else if(root->val>=low && root->val<=high){//左右两边都有可能在区间内
left=judgeNode(root->left,low,high);
right=judgeNode(root->right,low,high);
}
else if(root->val>high){
return judgeNode(root->left,low,high);
}
root->left=left;
root->right=right;
return root;
}
TreeNode* trimBST(TreeNode* root, int low, int high) {
//思路:首先考虑当前中间节点有三种情况,在low左边,在high右边
return judgeNode(root,low,high);
}
};
二刷:
思路二:递归
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(root==nullptr) return nullptr;
if(root->val<low) return trimBST(root->right,low,high);//从右子节点寻找
if(root->val>high) return trimBST(root->left,low,high);//从左子节点寻找
root->left=trimBST(root->left,low,high);//接住左子节点
root->right=trimBST(root->right,low,high);//接住右子节点
return root;//在区间内时依然返回子节点
}
};
108.将有序数组转换为二叉搜索树
思路一:使用两个指针分割区间,每次都选择中间的值作为根节点,然后向两边切割
class Solution {
public:
TreeNode*judge(vector<int>&nums,int left,int right){
if(left>right) return nullptr;
//每次都选择区间中间的数作为根节点
int mid=(left+right)/2;
TreeNode*root=new TreeNode(nums[mid]);
root->left=judge(nums,left,mid-1);
root->right=judge(nums,mid+1,right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
//思路一:高度平衡,递归切割
//后序遍历
return judge(nums,0,nums.size()-1);
}
};
分析:思路是这样,但是想复杂了,直接搞得分割区间,导致越来越乱
二刷路过:
class Solution {
public:
TreeNode*connectNode(vector<int>&nums,int left,int right){
if(left>right) return nullptr;//因为右边界取n-1,所以 left==right 在结果中
int index=left+(right-left)/2;
TreeNode*root=new TreeNode(nums[index]);
root->left=connectNode(nums,left,index-1);
root->right=connectNode(nums,index+1,right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return connectNode(nums,0,nums.size()-1);
}
};
538.把二叉搜索树转换为累加树
思路:遍历顺序为右中左,然后累加赋值
class Solution {
public:
int sum=0;
TreeNode* convertBST(TreeNode* root) {
//思路:遍历顺序为右中左,然后累加赋值
if(root!=nullptr){
convertBST(root->right);
sum+=root->val;
root->val=sum;
convertBST(root->left);
}
return root;
}
};
二刷:
class Solution {
public:
int sum=0;
TreeNode* convertBST(TreeNode* root) {
if(root==nullptr) return nullptr;
convertBST(root->right);//直接往右遍历
sum+=root->val;//累加右子节点
root->val=sum;//赋值
convertBST(root->left);//进入左子节点
return root;
}
};