LeetCode671. Second Minimum Node In a Binary Tree

来源:互联网 发布:origin有没有mac版 编辑:程序博客网 时间:2024/06/05 08:31

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 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.

给定一个特殊的二叉树,这个二叉树里的结点要么没有子结点,要么有两个子结点,根结点的值等于两个子结点中的较小值。
从这样的二叉树中找到第二小的值,若不存在第二小的值,则返回-1。

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

Explanation: The smallest value is 2, but there isn’t any second smallest value.

class TreeNode {    int val;    TreeNode left;    TreeNode right;    TreeNode(int x) { val = x; }}

这道题自己没有做出来,递归还是没递归清楚。这道题是自己找子问题找错了。

方法一:暴力破解

public int findSecondMinimumValue2(TreeNode root) {        if (root == null) {            return -1;        }        Set<Integer> set = new TreeSet<>();        dfs(root, set);//      Iterator<Integer> ite = set.iterator();//      while(ite.hasNext()){//          System.out.println(ite.next());//      }        Iterator<Integer> iterator = set.iterator();        int count = 0;        while (iterator.hasNext()) {            count++;            int result = iterator.next();            if (count == 2) {                return result;            }        }        return -1;}private void dfs(TreeNode root, Set<Integer> set) {        if (root == null) {            return;        }        set.add(root.val);        dfs(root.left, set);        dfs(root.right, set);}

关键点:

利用 Set 数据结构中不会出现重复元素的特点,先遍历树,将树中出现的所有的元素都放在 set 数据集中,然后在 Set 数据集中遍历元素,找到第二大的值。

疑问点:

  • Set 数据集不是不考虑元素的顺序吗?那为什么从 Set 数据集中取出的第二个值就是第二大的值?
  • 为了解决上面的疑问,在上面代码中加了注释掉的三行打印语句,发现打印的内容确实是按从小到大的顺序打印的,这是怎么回事呢?

解决上面疑问点:

注意:Set<Integer> set = new TreeSet<>();这里实现的是 TreeSet ,TreeSet 比散列集有所改进,树集是一个有序集合。可以以任意顺序将元素插入到集合中。在对集合进行遍历时,每个值将自动的按照排序后的顺序呈现。

按照上面暴力破解的思路,自己写的方法。

按照上面暴力破解的思路,自己写的方法。

不一样的是遍历 Set 数据集寻找第二大的值的方法,更易懂,没有上面的疑问。

public int findSecondMinimumValue2_my(TreeNode root){    if(root == null){        return -1;    }    Set<Integer> s = new HashSet<>();    dfs_my(root,s);    int ans = Integer.MAX_VALUE;    int min = root.val;    for (Integer item : s) {        if(item > min && item < ans){            ans = item;        }    }    if(ans == Integer.MAX_VALUE){        return -1;    }    else{        return ans;    }}public void dfs_my(TreeNode root, Set<Integer> s){    if(root == null){        return;    }    s.add(root.val);        dfs_my(root.left, s);    dfs_my(root.right, s);}

方法二:递归

public int findSecondMinimumValue1(TreeNode root) {        if (root == null) {            return -1;        }        if (root.left == null && root.right == null) {            return -1;        }        int left = root.left.val;        int right = root.right.val;        // if value same as root value, need to find the next candidate        if (root.left.val == root.val) {            left = findSecondMinimumValue1(root.left);        }        if (root.right.val == root.val) {            right = findSecondMinimumValue1(root.right);        }        if (left != -1 && right != -1) {            return Math.min(left, right);        } else if (left != -1) {            return left;        } else {            return right;        }}

关键点:

  • 寻找问题的子问题,什么情况下向下递归,自己就是理解错了这个才没有做出来。根据给定的二叉树的特点,只有当子结点的值与根结点的值相等的情况下才继续递归,不相等的时候不需要递归,该节点的值就相当于递归的返回值。

看了一遍递归的思路,自己按照思路写的。

    public int findSecondMinimumValue_my(TreeNode root) {        if(root == null) {            return -1;        }        if(root.left == null && root.right == null){            return -1;        }        int left = root.left.val;        int right = root.right.val;        if(root.val == root.left.val){            left = findSecondMinimumValue_my(root.left);        }        if(root.val == root.right.val){            right = findSecondMinimumValue_my(root.right);        }        if(left == -1 && right == -1){            return -1;        }        else if(left != -1 && right != -1){            return Math.min(left, right);        }        else if(left != -1){            return left;        }        else{            return right;        }}

思路相同,但是代码更简洁

    public int findSecondMinimumValue4(TreeNode root) {        if (root.left != null && root.right != null) {            int left = root.left.val, right = root.right.val;            if (root.left.val == root.val) {                left = findSecondMinimumValue4(root.left);            }            if (root.right.val == root.val) {                right = findSecondMinimumValue4(root.right);            }            if (left != -1 && right != -1) {                return Math.min(left, right);            }            else return left == -1 ? right : left;        }        else return -1;}
原创粉丝点击