每日小细节新增算法好题合集,现在是初阶,每天会更新至少两道题目,感兴趣的小伙伴赶紧关注收藏不迷路哦
花费几分钟就能积累一种新的解题思路多是一件美事啊~
1.验证搜索二叉树
其实这个很简单,但是容易错,他要保证根节点的val比左子树所有节点的val都大,比右子树所有节点val都小,而不是比左孩子,右孩子
所以说经典错误写法就是
bool isValidBST(struct TreeNode* root){
if(root==NULL)
{
return true;
}
if(root->left!=NULL && root->val <= root->left->val)
{
return false;
}
if(root->right!=NULL && root->val >= root->right->val)
{
return false;
}
return isValidBST(root->left) && isValidBST(root->right);
}
正确应该是找到一个区间,每次比较都把根节点放到区间里面,比如所有节点的val范围是[1,10],现在第一个根节点val是6,所以左子树的所有节点只能在[1,6) 右子树的所有节点只能在(6,10],然后递归依次插入root节点的val,不断细化区间,然后判断
bool _isvalidBST(struct TreeNode* root, long left, long right)
{
if(root==NULL)
return true;
if(root->val>=left || root->val<=right)
{
return false;
}
return _isvalidBST(root->right,left,root->val) && _isvalidBST(root->left,root->val,right);
}
bool isValidBST(struct TreeNode* root){
return _isvalidBST(root,LONG_MAX,LONG_MIN);
}
2.两数之和
原理和上一个差不多,还是遍历,从根节点开始,看两个节点的和是不是等于k,并且不是相同的节点,如果加起来大了,那就分别把两个节点递归到左子树,只要有一个成功就可以所以是或,相反,分别递归到右子树,也是有一个成功就可以
bool finder(struct TreeNode* small,struct TreeNode* big,int k)
{
if(small==NULL || big==NULL)
return false;
if(small->val+big->val > k)
{
return finder(small->left,big,k) || finder(small,big->left,k);
}
else if(small->val + big->val ==k && small!=big)
return true;
else
{
return finder(small->right,big,k) || finder(small,big->right,k);
}
}
bool findTarget(struct TreeNode* root, int k){
if(root==NULL || (root->left==NULL && root->right==NULL))
return false;
return finder(root,root,k);
}
3. 二叉搜索树的最近公共祖先
还是和之前两个是类似题,首先把祖先设成root,然后看p,q的val是不是分居祖先val的两侧,如果不是,q,p的val都比祖先的val小,那么把祖先变成他的左孩子
q,p的val都比祖先的val大,那么把祖先变成他的右孩子
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
struct TreeNode*ancestor=root;
while(true)
{
if(p->val < ancestor->val && q->val <ancestor->val)
ancestor=ancestor->left;
else if(p->val > ancestor->val && q->val >ancestor->val)
ancestor=ancestor->right;
else break;
}
return ancestor;
}