前言
二叉搜索树操作,继续。
记录 五十五【530.二叉搜索树的最小绝对差】
一、题目阅读
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
输入:root = [4,2,6,1,3]
输出:1
示例 2:
输入:root = [1,0,48,null,null,12,49]
输出:1
提示:
树中节点的数目范围是 [2, 10^4]
0 <= Node.val <= 10^5
二、尝试实现
思路
- 学过记录 五十四【98.验证二叉搜索树】 中一个特性:中序遍历得到有序递增的序列。
- 那么差值最小肯定是相邻元素作差。
- 确定遍历顺序:左中右。在中节点比较差值是否小于记录的最小值,所以用一个全局变量。
- 遍历过程中需要pre指针指向前一个遍历节点,方便在“中”处理逻辑比较。接近记录 五十四【98.验证二叉搜索树】代码。
- 处理返回值,如果用全局变量记录绝对值,那么返回值应该是void,所以需要另写一个函数,在主函数中调用它。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int result = INT_MAX;
TreeNode* pre = nullptr;//定义成全局变量,方便把pre返回上一层。
void traversal(TreeNode* cur){
if(!cur) return;
traversal(cur->left);
if(pre&& abs(pre->val - cur->val) < result){
result = abs(pre->val - cur->val) ;
}
pre = cur;
traversal(cur->right);
return;
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
感受:做到这题返回值处理不太好。想着能否直接在主函数中借助int的返回值,发现不合适。
三、参考学习
学习内容
确定思路正确。剩余就是实现方法。
-
第一种:借助数组开辟空间。
-
第二种,递归实现。使用两个指针,pre始终指向中间节点的前一个节点。和二、中的代码实现一样。
-
迭代法:思路不变。中序遍历的迭代实现。代码实现,个人习惯性先放入root,使用统一迭代的模版:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int getMinimumDifference(TreeNode* root) { int result = INT_MAX; TreeNode* pre = nullptr; stack<TreeNode*> st; st.push(root);//至少有两个节点,习惯性把节点先放入栈。所以采用统一迭代的模版 while(!st.empty()){ TreeNode* cur = st.top();st.pop(); if(cur){ if(cur->right) st.push(cur->right); st.push(cur); st.push(nullptr); if(cur->left) st.push(cur->left); }else{ TreeNode* node = st.top();st.pop();//要处理的对象 if(pre){ result = min(result,abs(pre->val - node->val)); } pre = node;//把当前处理的节点给到pre } } return result; } };
另一种迭代:参考代码。
总结
本文延续记录 五十四【98.验证二叉搜索树】的特性,使用双指针遍历。可以看作是【98.验证二叉搜索树】的练习题。