今天是二叉树
中序遍历,用一个指针记录前一个节点,计算当前节点与前一节点差值,与记录的最小值比较即可;因为二叉搜索树的中序遍历结果是一个有序的序列,我们只需要两两比较相邻的数,找出它们的最小差值即可
AC代码:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return _constructMaximumBinaryTree(nums, 0, nums.size() - 1);
}
TreeNode* _constructMaximumBinaryTree(vector<int>& nums, int left, int right) {
if (left > right) return nullptr;
int maxPos = left;
int maxVal = nums[left];
for (int i = left + 1; i <= right; ++i) {
if (nums[i] > nums[maxPos]) {
maxVal = nums[i];
maxPos = i;
}
}
TreeNode* root = new TreeNode(maxVal);
root->left = _constructMaximumBinaryTree(nums, left, maxPos - 1);
root->right = _constructMaximumBinaryTree(nums, maxPos + 1, right);
return root;
}
};
二叉搜索树的问题一般可以从中序遍历入手。
对于这道题,要求二叉搜索树的众数,因为二叉搜索树的中序遍历是有序的,因此我们可以先从有序数组如何求众数入手,即遍历一遍,在过程中记录每个数出现的次数,看是不是比之前记录的最大出现次数大,如果更大,那就代表出现了新的候选项,记录它,并抛弃之前记录的无效结果;如果相等,那就代表是复数的答案,记录它就行。
对于二叉树的遍历,要比较中序遍历相邻两节点的值,可以用一个指针记录前一个节点的值。
AC代码:
class Solution {
public:
TreeNode* prev;
vector<int> findMode(TreeNode* root) {
prev = nullptr;
vector<int> ans;
int count = 1;
int maxCount = 0;
inorder(root, ans, count, maxCount);
return ans;
}
// count和maxCount都要传递引用,因为遍历左子树时这两者可能会发生改变
void inorder(TreeNode* root, vector<int>& ans, int& count, int& maxCount)
{
if(root == nullptr) return;
inorder(root->left, ans, count, maxCount);
if(prev != nullptr){
if(prev->val == root->val){
count++;
}
else{
count = 1;
}
}
prev = root;
if(count > maxCount){
// count > maxCount时,要清空之前的无效结果,并更新maxCount
ans.clear();
ans.push_back(root->val);
maxCount = count;
}
else if(count == maxCount){
ans.push_back(root->val);
}
inorder(root->right, ans, count, maxCount);
}
};
一种直观的想法是,我们遍历整棵树,并在遍历的过程中记录从根节点到目标节点的路径,递归结束后我们就得到了从根节点到p和从根节点到q的两条路径,然后我们只需要从头开始依次比较两条路径上的节点,找到不相同的节点的前一个节点,就是我们要找的答案
另外一种是在遍历时就直接处理。代码如下:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
// root为空,直接返回
if(root == NULL) return NULL;
// root为要找的节点,直接返回
// 对应于q是p的孩子节点的情况(或者反过来也是一样的),我们会直接返回p,然后就结束后面的递归了
// 这是正确的,因为这种情况下答案就是p
if(root == p || root == q) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
// 要找的节点分别在当前root的左右子树中,那root就是答案
if(left != NULL && right != NULL) return root;
// 否则,返回不为空的那个结果
return left == NULL ? right : left;
}
};