Leetcode701
1.问题描述
2.解决方案
解法一:有返回值递归
1.递归因为是二叉搜索树自然不需要全树遍历,只需要根据大小确定递归方向这个很好理解
2.但是说实话这个递归过程的话,需要理解一下,其实我们之前的二叉树递归都不需要创造新的结点自然也不需要结点与结点之间的赋值,但是这个需要把插入的节点赋给其父亲节点,所以就出现了这样的递归过程
//if(val>root->val) return insertIntoBST(root->right,val);
//if(val<root->val) return insertIntoBST(root->left,val);
if(val>root->val) root->right=insertIntoBST(root->right,val);
if(val<root->val) root->left=insertIntoBST(root->left,val);
3.这个递归过程理解好了,这道题就基本没啥事情了!
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root== nullptr){
TreeNode* node=new TreeNode(val);
return node;
}
//if(val>root->val) return insertIntoBST(root->right,val);
//if(val<root->val) return insertIntoBST(root->left,val);
if(val>root->val) root->right=insertIntoBST(root->right,val);
if(val<root->val) root->left=insertIntoBST(root->left,val);
//百分之百不会从这走
//return nullptr;
return root;
}
};
解法二:无返回值递归
无返回值递归函数照样可以解决问题,这告诉我们问题永远有一般性的解法,各种解法都是可以的而不是看题解,每个题有每个题的解法,实则我们应该掌握的是所有题一种思路都可以解出来的理解程度!
1.无返回值递归就需要记录上一个节点parent,遇到空节点,就让parent的左/右孩子指向新节点并直接结束递归!
2.有两种写法,一种是把父节点写入递归函数参数,一种是变成全局,感觉参数更好理解一点
3.全局我一开始觉得有冲突问题也就是需要回溯不然肯定是错的,但是一想发现想多了,这是二叉搜索树,最终只会沿着一个方向进行下去,所以也不会有回溯的,但是如果有回溯全局就得多一步回溯,但是参数就不需要了因为是隐式回溯,如果回溯基础好的应该一下就明白了!
class Solution {
public:
void tran(TreeNode* root,TreeNode* parent,int val){
if(root== nullptr){
TreeNode* node=new TreeNode(val);
if(parent->val>val) parent->left=node;
if(parent->val<val) parent->right=node;
return;
}
if(val>root->val) tran(root->right,root,val);
if(val<root->val) tran(root->left,root,val);
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
//这一行必须有,不然上面的tran函数就得处理parent==nullptr&&root==nullptr的情况了
if(root== nullptr) return new TreeNode(val);
tran(root, nullptr,val);
return root;
}
};
class Solution {
public:
TreeNode* parent= nullptr;
void tran(TreeNode* root,int val){
if(root== nullptr){
TreeNode* node=new TreeNode(val);
if(parent->val>val) parent->left=node;
if(parent->val<val) parent->right=node;
return;
}
parent=root;
if(val>root->val) tran(root->right,val);
if(val<root->val) tran(root->left,val);
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
//这一行必须有,不然上面的tran函数就得处理parent==nullptr&&root==nullptr的情况了
if(root== nullptr) return new TreeNode(val);
tran(root,val);
return root;
}
};
解法三:迭代
迭代呢技巧就是记录parent和cur,找到插入点也就是cur==nullptr时,插入并返回根节点root
为什么好多题的迭代不给出了,这道题还是给出了是因为这是个还不错的记录前节点的迭代,若不是递归的翻版!
class Solution3 {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root== nullptr) return new TreeNode(val);
//开始寻找插入点
TreeNode* parent=root;
TreeNode* cur=root;
while(cur!= nullptr){
parent=cur;
if(cur->val>val) {cur=cur->left; continue;}
if(cur->val<val) {cur=cur->right; continue;}
}
//走到这说明cur==nullptr
TreeNode* node=new TreeNode(val);
if(parent->val>val) parent->left= node;
if(parent->val<val) parent->right= node;
return root;
}
};