目录
题目链接:530.二叉搜索树的最小绝对差
思路
相邻节点的最小绝对差,需要做差,就要同时访问两个节点,所以使用双指针。一个遍历,一个紧跟在后面,做差,比较,更新最小绝对差,直至遍历整个二叉树。
代码
class Solution {
public:
TreeNode* pre = NULL;
int result = INT_MAX;
void traversal(TreeNode* root) {
if (root == NULL)
return;
// 中序遍历,左中右
traversal(root->left); // 左
// 中
if (pre != NULL) {
int sub = abs(pre->val - root->val);
result = sub < result ? sub : result;
}
pre = root;
traversal(root->right); // 右
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
题目链接:501.二叉搜索树中的众数
思路
因为是二叉搜索树,按照中序遍历,遍历到的元素应该是单调不减(这里定义的二叉搜索树是可以存在相等元素的),因此使用双指针,每次对比相邻元素是否相等,如果相等,频率加一。为了寻找众数,需要找到出现频率最大的值,定义最大频率,每次迭代进行频率的对比,更新最大频率,如果更新,则清空结果数组,重新储存结果。
代码
class Solution {
public:
vector<int> result; // 结果数组
TreeNode* pre = NULL; // 双指针的pre指针
int count = 1; // 二叉树中每个元素最小的出现频率为1
int maxcount = 0; // 用来存储最大出现频率
// 根据本题题意,需要遍历整个二叉树,所以返回值为空
// 在遍历过程保存符合题意的结果即可
void traversal(TreeNode* cur) {
if (cur == NULL)
return;
// 中序遍历,左中右
// 左
traversal(cur->left);
// 中
if (pre != NULL && pre->val == cur->val) {
count++; // 相邻两个元素相等时,频率加1
} else {
count = 1; // 如果不等,频率置1
}
if (count == maxcount) {
// 如果当前元素的频率等于最大频率,加入结果数组
result.push_back(cur->val);
} else if (count > maxcount) {
// 如果当前元素频率比最大频率大
// 更新最大频率,清空数组,存入当前元素
maxcount = count;
result.clear();
result.push_back(cur->val);
}
pre = cur;
// 右
traversal(cur->right);
return;
}
vector<int> findMode(TreeNode* root) {
traversal(root);
return result;
}
};
题目链接:236. 二叉树的最近公共祖先
思路
求最近公共祖先,处理逻辑应该是从叶子节点往上,如果叶子节点出现了p或者q就把值往上返回,所以遍历顺序应该是后序遍历,左右中,先处理叶子节点,再处理中间节点。
代码
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL)
return root; // 空节点返回
if (root == p || root == q)
return root; // 遇到p或者q返回该节点
// 后序遍历,左右中
TreeNode* left = lowestCommonAncestor(root->left, p, q); // 左
TreeNode* right = lowestCommonAncestor(root->right, p, q); // 右
// 中
if (left == NULL && right == NULL) {
return NULL; // 都为空,并未找到祖先,返回NULL
} else if (left == NULL && right != NULL) {
return right; // 右子树返回值不为空,右子树找到了p或者q或者公共祖先
} else if (left != NULL && right == NULL) {
return left; // 同理
} else {
return root; // 都不为空,已经找到公共祖先,返回下面传上来的返回值即可
}
}
};
总结
①加深理解二叉树的遍历
②加深理解二叉树中的双指针法
③找众数这道题对于最大频率更新,结果数组更新的处理十分巧妙,记住这个处理方法。先存后更新,遍历完毕后存的就是符合条件的结果