Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes.

Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in the whole tree.

If no such second minimum value exists, output -1 instead.

Example 1:

Input:
2
/ \
2 5
/ \
5 7 Output: 5
Explanation: The smallest value is 2, the second smallest value is 5.

Example 2:

Input:
2
/ \
2 2 Output: -1
Explanation: The smallest value is 2, but there isn't any second smallest value.

这道题让我们找二叉树中的第二小的结点值,并且给该二叉树做了一些限制,比如对于任意一个结点,要么其没有子结点,要么就同时有两个子结点,而且父结点值是子结点值中较小的那个,当然两个子结点值可以相等。那么直接上暴力搜索呗,根据该树的附加条件可知,根结点一定是最小的结点值first,那么我们只要找出第二小的值second即可,初始化为整型的最大值。然后对根结点调用递归函数,将first和second当作参数传进去即可。在递归函数中,如果当前结点为空,直接返回,若当前结点孩值不等于first,说明其肯定比first要大,然后我们看其是否比second小,小的话就更新second,然后对当前结点的左右子结点分别调用递归函数即可,参见代码如下:

解法一:

class Solution {
public:
int findSecondMinimumValue(TreeNode* root) {
int first = root->val, second = INT_MAX;
helper(root, first, second);
return (second == first || second == INT_MAX) ? - : second;
}
void helper(TreeNode* node, int& first, int& second) {
if (!node) return;
if (node->val != first && node->val < second) {
second = node->val;
}
helper(node->left, first, second);
helper(node->right, first, second);
}
};

下面这种方法也是用递归来做的,不过现在递归函数有了返回值,在递归函数中,还是先判断当前结点是否为空,为空直接返回-1。然后就是看当前结点是否等于first,不等于直接返回当前结点值。如果等于,我们对其左右子结点分别调用递归函数,分别得到left和right。如果left和right其中有一个为-1了,我们取其中的较大值;如果left和right都不为-1,我们取其中的较小值返回即可,参见代码如下:

解法二:

class Solution {
public:
int findSecondMinimumValue(TreeNode* root) {
return helper(root, root->val);
}
int helper(TreeNode* node, int first) {
if (!node) return -;
if (node->val != first) return node->val;
int left = helper(node->left, first), right = helper(node->right, first);
return (left == - || right == -) ? max(left, right) : min(left, right);
}
};

下面这种递归方法更加简洁了,没有再使用专门的递归函数helper,而是对当前根结点判断其左子树是否存在,不存在就返回-1。题目中说了是非空树,所以根结点一定存在。然后我们比较如果左子结点值等于根结点值,我们则对其左子结点调用递归函数;否则left就等于其左子结点值。再比较如果右子结点值等于根结点值,则对其右子结点调用递归函数;否则right就等于其右子结点值。最后我们还是看如果left和right其中有一个为-1了,我们取其中的较大值;如果left和right都不为-1,我们取其中的较小值返回即可,参见代码如下:

解法三:

class Solution {
public:
int findSecondMinimumValue(TreeNode* root) {
if (!root->left) return -;
int left = (root->left->val == root->val) ? findSecondMinimumValue(root->left) : root->left->val;
int right = (root->right->val == root->val) ? findSecondMinimumValue(root->right) : root->right->val;
return (left == - || right == -) ? max(left, right) : min(left, right);
}
};

整了三种递归的解法,来看一种迭代的解法吧,用的是层序遍历,但还是用的解法一种的不停更新second的方法,参见代码如下:

解法四:

class Solution {
public:
int findSecondMinimumValue(TreeNode* root) {
int first = root->val, second = INT_MAX;
queue<TreeNode*> q{{root}};
while (!q.empty()) {
auto t = q.front(); q.pop();
if (t->val != first && t->val < second) {
second = t->val;
}
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
return (second == first || second == INT_MAX) ? - : second;
}
};

类似题目:

Kth Smallest Element in a BST

参考资料:

https://discuss.leetcode.com/topic/102277/java-4-lines

https://discuss.leetcode.com/topic/102027/c-dfs-recursion

https://discuss.leetcode.com/topic/102035/bfs-acc-solution-java-and-c-code

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Second Minimum Node In a Binary Tree 二叉树中第二小的结点的更多相关文章

  1. LeetCode 671. Second Minimum Node In a Binary Tree二叉树中第二小的节点 (C++)

    题目: Given a non-empty special binary tree consisting of nodes with the non-negative value, where eac ...

  2. Leetcode671.Second Minimum Node In a Binary Tree二叉树中的第二小结点

    给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0.如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值. 给出这样的一个二叉树,你需要输出所有节点中 ...

  3. [LeetCode] Closest Leaf in a Binary Tree 二叉树中最近的叶结点

    Given a binary tree where every node has a unique value, and a target key k, find the value of the n ...

  4. LeetCode Second Minimum Node In a Binary Tree

    原题链接在这里:https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/description/ 题目: Given a ...

  5. LeetCode 671. Second Minimum Node In a Binary Tree

    Given a non-empty special binary tree consisting of nodes with the non-negative value, where each no ...

  6. LeetCode 671. 二叉树中第二小的节点(Second Minimum Node In a Binary Tree) 9

    671. 二叉树中第二小的节点 671. Second Minimum Node In a Binary Tree 题目描述 给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 ...

  7. 【Leetcode_easy】671. Second Minimum Node In a Binary Tree

    problem 671. Second Minimum Node In a Binary Tree 参考 1. Leetcode_easy_671. Second Minimum Node In a ...

  8. Java实现 LeetCode 671 二叉树中第二小的节点(遍历树)

    671. 二叉树中第二小的节点 给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0.如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值. 给出这样的 ...

  9. 【LeetCode】671. Second Minimum Node In a Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 找出所有值再求次小值 遍历时求次小值 日期 题目地址 ...

随机推荐

  1. 使用selenium时提示:ImportError:No module named selenium

    问题分析: 用的是mac系统,已经通过sudo pip install -U selenium安装好了selenium, 但是无论用命令行还是用sublime导入selenium都会提示错误. 于是查 ...

  2. 安装texlive2017(latex的编译软件)

    准备工作是先卸载老版本的texlive,这个只要找到原来安装时的安装目录,然后直接把整个文件夹删掉即可.然后找到最近的Ctan的镜像,下载到对应版本的texlive,例如Mac系统,最好用的就是tex ...

  3. js面向对象的理解

    ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScrip ...

  4. Elasticsearch安装详解

    本文只介绍在windows上的安装和配置,其他安装和配置请参见官方文档 ES在windows上安装需下载zip安装包,解压后bin目录下有个 elasticsearch-service.bat 文件. ...

  5. Beta Scrum Day 6

    听说

  6. C语言嵌套循环

    题目一:7-3 编程打印空心字符菱形 1.提交列表 2.设计思路: 1.定义整型变量循环控制变量i,j,k,x,y,z,e及菱形的高度height: 2.定义字符型变量letter: 3.输入字符型变 ...

  7. C语言博客作业—指针

    一.PTA实验作业 题目1: 求出数组中最大数和次最大数 1. 本题PTA提交列表 2. 设计思路 定义max表示范围数组中的最大数(初值设为a[0]),z表示找到的元素在数组中的位置: 定义指针*b ...

  8. codevs 1291 火车线路

    http://codevs.cn/problem/1291/ 题目描述 Description 某列火车行使在C个城市之间(出发的城市编号为1,结束达到的城市的编号为C),假设该列火车有S个座位,现在 ...

  9. C#系统服务安装

    转载 http://blog.csdn.net/vvhesj/article/details/8349615 1.1创建WindowsService项目 导入需要的引用比如System.configu ...

  10. Python脚本自动提取和替换代码中的中文

    # -*- coding: utf-8 -*- import os import os.path import re import sys reload(sys) sys.setdefaultenco ...