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.
题意:给定一颗二叉树,返回二叉树中第二最小的结点值,如果不存在第二最小值,则返回-1。对于给定二叉树的规定:
1. 二叉树非空,且二叉树中的结点值非负;
2. 二叉树中每个结点要么有两个子结点,要么没有子结点;
如果某父结点有两个子结点,则父结点是两个子结点中的较小值,其中两个子结点值可以相等。
思路:根结点一定是最小值。采用遍历的方法逐个判断是否为第二小元素,实现如下:
public int findSecondMinimumValue(TreeNode root) { int sMin = root.val, min = root.val; Queue<TreeNode> q = new LinkedList<>(); q.offer(root); while(!q.isEmpty()){ TreeNode t = q.poll(); if((sMin == min || t.val < sMin) && t.val > min)//sMin == min来获取第一个比root.val大的元素 sMin = t.val; if(t.left != null) q.offer(t.left); if(t.right != null) q.offer(t.right); } return sMin == min ? -1 : sMin; }
LeetCode提供的算法1:
先使用深度优先搜索的方法遍历二叉树,并利用set不包含重复元素的特性,将树中的结点存入set对象;然后再找第二小的元素。
public void dfs(TreeNode root, Set<Integer> uniques){ if(root != null){ uniques.add(root.val); dfs(root.left, uniques); dfs(root.right, uniques); } } public int findSecondMinimumValue(TreeNode root){ Set<Integer> uniques = new HashSet<>(); dfs(root, uniques); int min = root.val; long second = Long.MAX_VALUE; for(int val : uniques){ if(val > min && val < second) second = val; } return (int) (second == Long.MAX_VALUE ? -1 : second); }
算法2:对算法1进行改进,因为只需要找第二小的值,因此不需要存储树中所有不重复出现的元素。当遍历某个结点node时,如果node.val > min,则说明该结点node的子树的所有值都大于等于node.val,因此结点node的子树中就不用再判断了。
int min; long ans = Long.MAX_VALUE; public void dfs(TreeNode root){ if(root != null){ if(root.val > min && root.val < ans) ans = root.val; else if(root.val == min){ dfs(root.left); dfs(root.right); } } } public int findSecondMinimumValue(TreeNode root){ min = root.val; dfs(root); return ans < Long.MAX_VALUE ? (int) ans : -1; }