1. 题目来源
2. 题目解析
方法一:
-
本题是要求树中的次小值。关于求次小值有一个通用方法,用
d1,d2
来维护最小值和次小值,如果当前值x<d1
则d2=d1, d1=x
,否则如果d1<=x<d2
则,d2=x
即可。 -
这样一次遍历,就能得到最小值和次小值。故,直接遍历一遍树即可。
-
本题数据范围比较大,注意初始化
d1=d2=1e18
,需要开LL
。
方法二:
- 本题由于树的定义的特殊性,树的根节点一定是所有节点中最小的一个,那么只需要求得严格大于树根节点的值中最小的一个即可。 即如果当前遍历节点大于树根节点,那么更新的答案,维护一个最小值即可。初始化为
LL
,注意取min
维护答案的时候要强转成类型一致的。
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码:
方法一,通用方法维护次小值即可。
/**
* 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:
using LL = long long;
LL d1, d2;
void dfs(TreeNode* root) {
if (!root) return ;
int x = root->val;
if (x < d1) d2 = d1, d1 = x;
else if (x > d1 && x < d2) d2 = x;
dfs(root->left);
dfs(root->right);
}
int findSecondMinimumValue(TreeNode* root) {
d1 = d2 = 1e18;
dfs(root);
return d2 == 1e18 ? -1 : d2;
}
};
方法二,找到大于根节点的最小值。
/**
* 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:
using LL = long long;
void dfs(TreeNode* root, LL x, LL &res) {
if (!root) return ;
if (root->val > x) res = min(res, (LL)root->val);
dfs(root->left, x, res);
dfs(root->right, x, res);
}
int findSecondMinimumValue(TreeNode* root) {
LL res = 1e18;
dfs(root, root->val, res);
return res == 1e18 ? -1 : res;
}
};