Leetcode 530.二叉搜索树的最小绝对差
思路分析:
本题可按中序遍历把二叉搜索树的值保存到数组中,然后遍历数组找到差值的最小值。此解法虽然容易理解,但不提倡。可以在中序遍历二叉搜索树时就处理出结果。可以保存上一帧的节点pre_node, 递归的单层逻辑里可以判断root->val和pre_node->val的差值,如果小于min_diff则更新min_diff,最后返回min_diff.
代码实现:
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
if (root==nullptr) return 0;
travesal(root);
return min_diff;
}
private:
TreeNode* pre_node = nullptr;
int min_diff = INT_MAX;
void travesal(TreeNode* root) {
if (root == nullptr) return;
travesal(root->left);
if (pre_node != nullptr && root->val - pre_node->val < min_diff) {
min_diff = root->val - pre_node->val;
}
pre_node = root;
travesal(root->right);
}
};
Leetcode 501.二叉搜索树中的众数
思路分析:
本题的直观思路是中序遍历将二叉搜索树的元素放入unordered_map中,并统计每个元素出现的次数,最后遍历unordered_map,找到出现频率最高的元素。见方法1.
还有进阶的解法,不适用unordered_map,中序遍历,单层逻辑里就找出当前元素出现的次数currFreq,然后找到出现频率最高的次数和对应的元素。最后返回result.见方法2.
代码实现:
class Solution {
public:
vector<int> findMode(TreeNode* root) {
vector<int> result;
if (!root) return result;
traverse(root);
int maxFreq = 0;
for (const auto &entry : frequency) {
if (entry.second == maxFreq) {
result.push_back(entry.first);
} else if (entry.second > maxFreq) {
maxFreq = entry.second;
result = {entry.first};
}
}
return result;
}
private:
unordered_map<int, int> frequency;
void traverse(TreeNode* node) {
if (node == nullptr) return;
traverse(node->left);
frequency[node->val]++;
traverse(node->right);
}
};
进阶:不使用额外的空间版本
class Solution {
public:
vector<int> findMode(TreeNode* root) {
vector<int> result;
if (!root) return result;
int prev = INT_MIN;
int maxFreq = 0, currFreq = 1;
traverse(root, prev, maxFreq, currFreq, result);
return result;
}
private:
void traverse(TreeNode* node, int& prev, int& maxFreq, int& currFreq, vector<int>& result) {
if (node == nullptr) return;
traverse(node->left, prev, maxFreq, currFreq, result);
if (node->val == prev) {
currFreq++;
} else {
currFreq = 1;
}
if (currFreq > maxFreq) {
result.clear();
maxFreq = currFreq;
result.push_back(node->val);
} else if (currFreq == maxFreq) {
result.push_back(node->val);
}
prev = node->val;
traverse(node->right, prev, maxFreq, currFreq, result);
}
};
Leetcode 236. 二叉树的最近公共祖先
思路分析:
首先注意题目提示,所有Node.val互不相同,p!=q,p和q均存在于给定的二叉树中。找祖先问题适合自底向上遍历,由此很好想到用后序遍历,用递归法较易实现。
本题需要遍历整棵树才能找到所有可能pq的最近公共祖先,因此,递归函数是需要有返回值的。递归函数的结束条件是root节点为p或q节点,或root为空节点。递归的单层逻辑是:1.如果左右节点都不为空,则该root就是最近公共节点,返回root;2.如果左节点为空,右节点不为空,则返回右节点;3.如果左节点不为空,右节点为空,则返回左节点;4.如果左右节点都为空,则返回空节点。注意2和3中之所以返回的是左节点或右节点,而不是root节点,是因为这种情况下,root一定不是最近的公共祖先,最近的公共祖先在左右节点中产生。
代码实现:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root==p || root==q || root==nullptr)
return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if (left != nullptr && right != nullptr) {
return root;
} else if (left == nullptr && right != nullptr) {
return right;
} else if (left != nullptr && right == nullptr) {
return left;
} else {
return nullptr;
}
}
};