LeetCode 530. 二叉搜索树的最小绝对差
解法一
思路:将二叉搜索树可以看作一个从小到大排列的有序数组,相邻数比较大小,就简单多了
class Solution {
public:
vector<int> vec;
void traversal(TreeNode* root){
if(!root)return ;
traversal(root->left);
vec.push_back(root->val);
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
int result=INT_MAX;
traversal(root);
for(int i=1;i<vec.size();i++){
result=result<vec[i]-vec[i-1] ? result:vec[i]-vec[i-1];
}
return result;
}
};
解法二
class Solution {
public:
int result=INT_MAX;
TreeNode* pre=NULL;
void traversal(TreeNode* root){
if(!root)return ;
traversal(root->left);
if(pre)result=min(result,root->val-pre->val);
pre=root;
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
这里用中序遍历,符合从大到小的顺序。
pre指向的是遍历的前一个节点,记录每一个前面的节点,后面-前面。
LeetCode 501. 二叉搜索树中的众数
解法一
class Solution {
public:
unordered_map<int,int> map;
void serchBST(TreeNode* root){
if(!root)return ;
map[root->val]++;
serchBST(root->left);
serchBST(root->right);
}
bool static cmp(pair<int,int>& a,pair<int,int>& b){
return a.second>b.second;
}
vector<int> findMode(TreeNode* root) {
vector<int> result;
if(!root)return result;
serchBST(root);
vector<pair<int,int>> vec(map.begin(),map.end());
sort(vec.begin(),vec.end(),cmp);
result.push_back(vec[0].first);
for(int i=1;i<vec.size();i++){
if(vec[i].second==vec[0].second)result.push_back(vec[i].first);
else break;
}
return result;
}
};
这种解法是通用解法,并没有体现出二叉搜索树的特点。
就是全部遍历一遍,哪种遍历方法都可以,然后将数出现频率存储到map中,根据键值对存储频率排序,由大到小添加到result数组中输出。
LeetCode 236. 二叉树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL || root==p || root==q)return root;
TreeNode* left=lowestCommonAncestor(root->left,p,q);
TreeNode* right=lowestCommonAncestor(root->right,p,q);
if(left!=NULL && right!=NULL)return root;
else if(left!=NULL || right!=NULL)return left!=NULL ? left:right;
else return NULL;
}
};
这个题目比较牛,回溯的思想比较独特,我看完代码看了几遍都不能一下子理解。
- 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。这一点很重要,中节点的状态需要通过左子树,右子树来判断。所以回溯只能用后序遍历来做。
- 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
- 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
具体代码思路,记录找到的最近公共祖先位置,然后不断将这个位置进行向上返回,left和right只要找到了所要求的位置,所记录的节点实际上就不会变了,left和right就不断向上返回,返回的其实都是同一个节点,即被记录的节点,只不过它可能以left或right的形式出现。