530.二叉搜索树的最小绝对差
这道题和验证二叉搜索树思路几乎相同,因为二叉搜索树的特殊,最小绝对差一定是在中序遍历的相邻两个节点之间,因此需要把上一个节点保存下来,然后进行计算,使用的遍历方式是中序遍历,具体细节不再赘述,详细代码如下:
class Solution {
public:
TreeNode* pre = nullptr;
int min_res = INT_MAX;
void dfs(TreeNode* root)
{
if(root==nullptr) return ;
dfs(root->left);//左
//中
if(pre!=nullptr)
{
min_res = min(min_res,root->val-pre->val);
}
pre = root; //保存前一节点
dfs(root->right);
}
int getMinimumDifference(TreeNode* root) {
dfs(root);
return min_res;
}
};
501. 二叉搜索树中的众数
这道题目中有强调众数可能不止一个,所以我的思路是统计每个节点val的个数,同时维护一个出现最高的频率,把每个节点出现的次数保存在哈希表中, 最后再遍历哈希表,value==最高频率的节点放入结果vector中,详细代码如下:
(写代码时犯了一个语法错误:在遍历哈希表的时候,取迭代器中对应的元素不需要用指针,直接it->first就可)
class Solution {
public:
//TreeNode* pre = nullptr;
unordered_map<int, int> map;
int count=0;
void dfs(TreeNode* root)
{
if(root==nullptr) return ;
dfs(root->left);
//中
map[root->val]++;
count = max(count, map[root->val]);
dfs(root->right);
}
vector<int> findMode(TreeNode* root) {
if(root==nullptr) return {};
vector<int> res;
dfs(root);
for(unordered_map<int,int>::iterator it = map.begin();it!=map.end();it++)
{
if(it->second==count) res.push_back(it->first);
}
return res;
}
};
但是我的思路没有用到二叉搜索树的性质,用到二叉搜索树的性质则不需要额外的空间,且一遍就可以得到众数,思路比较巧妙:
弄一个指针指向前一个节点,这样每次cur(当前节点)才能和pre(前一个节点)作比较。
而且初始化的时候pre = NULL,这样当pre为NULL时候,我们就知道这是比较的第一个元素。
代码如下:
if (pre == NULL) { // 第一个节点
count = 1; // 频率为1
} else if (pre->val == cur->val) { // 与前一个节点数值相同
count++;
} else { // 与前一个节点数值不同
count = 1;
}
pre = cur; // 更新上一个节点
因为要求最大频率的元素集合(注意是集合,不是一个元素,可以有多个众数),如果是数组上大家一般怎么办?其实只需要遍历一次就可以找到所有的众数。
如果 频率count 等于 maxCount(最大频率),当然要把这个元素加入到结果集中(以下代码为result数组),代码如下:
if (count == maxCount) { // 如果和最大值相同,放进result中
result.push_back(cur->val);
}
是不是感觉这里有问题,result怎么能轻易就把元素放进去了呢,万一,这个maxCount此时还不是真正最大频率呢。
所以下面要做如下操作:
频率count 大于 maxCount的时候,不仅要更新maxCount,而且要清空结果集(以下代码为result数组),因为结果集之前的元素都失效了。
if (count > maxCount) { // 如果计数大于最大值
maxCount = count; // 更新最大频率
result.clear(); // 很关键的一步,不要忘记清空result,之前result里的元素都失效了
result.push_back(cur->val);
}
最终详细代码如下:
class Solution {
public:
TreeNode* pre =nullptr;
int max_count = 0;
int count = 0;
vector<int> res;
void dfs(TreeNode* root)
{
if(root==nullptr) return ;
dfs(root->left);
//中
if(pre==nullptr) count=1;
else if(pre->val==root->val) count++;
else count=1; //值不相等
if(count==max_count) res.push_back(root->val); //相同出现的频率次数可以添加
else if(count>max_count) //出现频率更高的数
{
max_count = count;
res.clear(); //清空数组,前面的都是都不是众数
res.push_back(root->val);
}
pre = root; //更新pre
dfs(root->right);
}
vector<int> findMode(TreeNode* root) {
dfs(root);
return res;
}
};
236. 二叉树的最近公共祖先
这道题目使用后序遍历来解决,代码看起来比较简洁,但涉及到的细节思想比较多,看代码随想录消化,后面还需巩固,详细代码如下:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr||root==p||root==q) return root;
TreeNode* leftt = lowestCommonAncestor(root->left, p, q);
TreeNode* rightt = lowestCommonAncestor(root->right, p,q);
if(leftt!=nullptr&&rightt!=nullptr) return root;
else if(leftt==nullptr) return rightt;
else return leftt;
}
};