这里写目录标题
530. 二叉搜索树的最小绝对差
思路
题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。
注意是二叉搜索树,二叉搜索树可是有序的。
递归
1.数组.在一个有序数组上求两个数最小差值,把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。
2.用一个pre节点记录一下cur节点的前一个节点
class Solution {
public:
TreeNode* newnode=nullptr;//TreeNode* newnode=new TreeNode()不可以,传人的值为0
int minval=INT_MAX;
void traversal(TreeNode* root)
{ if(root==nullptr)return;
traversal(root->left);
if(newnode!=nullptr)
{
minval=min(minval,root->val-newnode->val);
}
newnode=root;
traversal(root->right);
}
int getMinimumDifference(TreeNode* root)
{
traversal(root);
return minval;
}
};
中序迭代
class Solution {
public:
int getMinimumDifference(TreeNode* root)
{
int minval=INT_MAX;
TreeNode* node=nullptr;
if(root==nullptr)return 0;
stack<TreeNode*>input;
input.push(root);
while(!input.empty())
{
TreeNode* cur=input.top();
if(cur!=nullptr)
{
input.pop();
if(cur->right)input.push(cur->right);
input.push(cur);
input.push(nullptr);
if(cur->left)input.push(cur->left);
}
else
{
input.pop();
cur=input.top();
input.pop();
if(node!=nullptr) minval=min(minval,cur->val-node->val);
node=cur;
}
}
return minval;
}
};
501. 二叉搜索树中的众数
思路
递归
1.对于非二叉搜索树:
采用遍历,将数存放到map里统计频率
2.对于二叉搜索树:中序遍历有顺序
1.从头中序遍历,那么一定是对相邻的两个元素作比较,然后就把出现频率最高的元素输出就可以了。
2.采用双指针,pre和cur进行比较,初始化pre=nullptr,统计当前单一元素出现频率
if(pre==nullptr) count=1;/当前cur指向最下面的左节点,则pre指向了cur下面的空节点,所以当前元素频率计数为1;
else if(pre->val==cur->val) count++;
else count=1;/pre和cur数值不相等,当前值的计数又变为1
3.求最大频率的集合:一次遍历搜索树
如下操作:频率count 大于
maxCount的时候,不仅要更新maxCount,而且要清空结果集(以下代码为result数组),因为结果集之前的元素都失效了。
if(count>maxcount)//更新maxcount
{
maxcount=count;
result.clear();
result.push_back(cur->val);
}
代码
class Solution {
public:
int count=0;//统计当前元素出现计数
int maxcount=0;//统计这个元素出现最多的数
TreeNode* pre=nullptr;
vector<int>result;
void traversal(TreeNode* cur)
{
if(cur==nullptr)return;
traversal(cur->left);
if(pre==nullptr)
{
count=1;//cur指向最下面的左节点,则pre指向了cur下面的空节点,所以当前元素频率计数为1;
}
else if(pre->val==cur->val) count++;
else//pre和cur数值不相等,当前的值重新计数
{
count=1;
}
pre=cur;
if(count==maxcount)result.push_back(cur->val);
if(count>maxcount)//更新maxcount
{
maxcount=count;
result.clear();
result.push_back(cur->val);
}
traversal(cur->right);
}
vector<int> findMode(TreeNode* root) {
traversal(root);
return result;
}
};
迭代:中序遍历的迭代法,其中间处理逻辑一点都没有变
class Solution {
public:
vector<int> findMode(TreeNode* root) {
int count=0;
int maxcount=0;
vector<int>result;
TreeNode* pre=nullptr;
stack<TreeNode*>input;
if(root==nullptr)return result;
input.push(root);
while(!input.empty())
{
TreeNode* cur=input.top();
if(cur!=nullptr)
{
input.pop();
if(cur->right) input.push(cur->right);
input.push(cur);
input.push(nullptr);
if(cur->left) input.push(cur->left);
}
else
{
input.pop();
cur=input.top();
input.pop();
if(pre==nullptr)count=1;
else if(pre->val==cur->val)count++;
else count=1;
if(count==maxcount)result.push_back(cur->val);
if(count>maxcount)
{
maxcount=count;
result.clear();
result.push_back(cur->val);
}
pre=cur;
}
}
return result;
}
};
236. 二叉树的最近公共祖先
思路:
通过后序遍历,自底向上查找
情况一:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
情况二:
情况一 和 情况二 代码实现过程都是一样的,也可以说,实现情况一的逻辑,顺便包含了情况二。
递归
1.确定递归函数返回值和参数
代码
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
2.确定终止条件
遇到空的话,因为树都是空了,所以返回空。如果root等于q/p ,说明找到 q p ,则将其返回,这个返回值,后面在中节点的处理过程中会用到
if(root==nullptr)return nullptr;
if(root==p||root==q)return root;
情况2包含在情况1里面,因为roo==q/p之间返回了。
3.单层递归逻辑和中节点的处理逻辑,
递归逻辑
left = 递归函数(root->left); // 左
right = 递归函数(root->right); // 右
left与right的逻辑处理; // 中
4.中间节点处理逻辑
1.如果left 和 right都不为空,说明此时root就是最近公共节点
2.如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然。 如图,对于节点10,左子树返回为空,右子树返回7,所以节点10向上返回右子树的7
注意:else return nullptr;//都为空,返回空,要用else,因为还有||情况
if(left!=nullptr&&right!=nullptr)return root;//左右子树分别出现pq
if(left==nullptr&&right!=nullptr) return right;//左子树为空,右不为空分别出现pq
else if(left!=nullptr&&right==nullptr) return left;
else return nullptr;//都为空,返回空,要用else,因为还有||情况
完整代码
class Solution {
public://后序遍历,左右中
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr)return nullptr;
if(root==p||root==q)return root; //情况2包含在情况1里面,因为roo==q/p之间返回了。
TreeNode* left=lowestCommonAncestor(root->left,p,q);//左和右递归返回的值
TreeNode* right=lowestCommonAncestor(root->right,p,q);
if(left!=nullptr&&right!=nullptr)return root;//左右子树分别出现pq
if(left==nullptr&&right!=nullptr) return right;//左子树为空,右不为空分别出现pq
else if(left!=nullptr&&right==nullptr) return left;
else return nullptr;//都为空,返回空,要用else,因为还有||情况
}
};