TMCB电话面试题

题目:

2) Write code to find the 2nd smallest element in a binary search tree (BST) .

Java

class Node {

public Node left;

public Node right;

public Node parent;

public int value;

}

C++

class Node {

public:

Node *left;

           Node *right;

          Node *parent;

          int value;

}

Python

class Node:
   def __init__(self, val):
       self.l_child = None
       self.r_child = None

       self.parent=None
       self.value = val

解决方案:

首先确认了是BST,所以所有的数据是排序的,第一思路是做一个中序扫描(先左再根后右),然后读取第二个元素。当时电话里也仅仅做到了这一步没有继续下去,但是也给了我机会去面试。现在有时间,想到的一个优化算法是,在做排序的过程中,一旦找到了第二小的元素,便跳出扫描,跳出递归的方式用流行的自定义RuntimeException的方式,代码如下:

public class TMC {

    @SuppressWarnings("serial")
    static class StopRecursorException extends RuntimeException {
    }

    private int secNum;

    public int getSec(TMCNode root) {
        secNum = Integer.MIN_VALUE;
        try {
            int count = 0;
            count = midTravel(root, count);
            return secNum; // nodes less than 2
        } catch (StopRecursorException e) {
            return secNum;
        }
    }

    public int midTravel(TMCNode root, int count) {
        if (root != null) {
            midTravel(root.left, count);
            ++count;
            if (count == 2) { // second smallest
                secNum = root.value;
                throw new StopRecursorException();
            }
            midTravel(root.right, count);
        }
        return count;
    }
}

class TMCNode {
    public TMCNode left;
    public TMCNode right;
    public TMCNode parent;
    public int value;

    public TMCNode(TMCNode left, TMCNode right, TMCNode parent, int value) {
        this.left = left;
        this.right = right;
        this.parent = parent;
        this.value = value;
    }
}

我相信我现在给出的方法还不是面试官所期待的最优算法,这个node的设置里面有parent,这个父节点我根本没有用到。

关于这个问题有个详尽版本在http://www.geeksforgeeks.org/find-k-th-smallest-element-in-bst-order-statistics-in-bst

还有诸多讨论在http://stackoverflow.com/questions/2329171/find-kth-smallest-element-in-a-binary-search-tree-in-optimum-way

update:

在查询改问题的时候,有个回复提到了,找到最小值以后,再找一次最小值就是第二小的数,所以当问题是确定了第二小的时候,有这样的解法:

public int find2ndSmallest(TMCNode node) {
    TMCNode currentNode = node; // here also a bug, need check if root is null or not
    while (currentNode.left != null) {
        currentNode = currentNode.left;
    } // after this loop, we reach the smallest (left end)
    if (currentNode.right == null) { // no child, parent is second smallest
        return currentNode.parent.value; // here is a bug, if root need return less than 2 nodes
    } else { // right child
        currentNode = currentNode.right;
        while (currentNode.left != null) {
            currentNode = currentNode.left;
        } // find smallest in right child tree
        return currentNode.value;
    }
}

做出这个解法的时候我想起了当初在LCM(Shanghai)面试的时候,马博士给我的一个比赛冠军题,然后问道亚军如何计算。1对1的比赛其实就是二叉树,确定冠军的时候,找亚军又是一个可以简化的问题。

发现自己还有很多题可以啃。

原文地址:https://www.cnblogs.com/t--c---/p/3775689.html