今天我接受了一次采访,我被要求编写一个采用二叉树的程序,如果它也是二进制搜索树则返回true,否则为假。
我的方法1:执行有序遍历并将元素存储在O(n)时间内。现在扫描数组/元素列表,检查i th 索引处的元素是否大于(i + 1) th 索引处的元素。如果遇到这种情况,则返回false并退出循环。 (这需要O(n)时间)。最后返回true。
但这位先生希望我提供一个有效的解决方案。我尝试了但是我没有成功,因为要查找它是否是BST我必须检查每个节点。
此外,他指着我思考递归。 我的方法2:如果对于任何节点N N> left是
但这会很复杂,而且运行时间似乎并不好。如果您知道任何最佳解决方案,请提供帮助。
答案 0 :(得分:78)
以下答案是一个众所周知的问题:
public boolean isValid(Node root) {
return isValidBST(root, Integer.MIN_VALUE,
Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
if(node == null)
return true;
return node.value > l
&& node.value < h
&& isValidBST(node.left, l, node.value)
&& isValidBST(node.right, node.value, h);
}
递归调用确保子树节点在其祖先的范围内,这很重要。运行时复杂度为O(n),因为每个节点都要检查一次。
另一个解决方案是进行inorder遍历并检查序列是否已排序,尤其是因为您已经知道提供了二叉树作为输入。
答案 1 :(得分:7)
@Dhruv提供的答案很好。除此之外,这是另一种在O(n)时间内工作的解决方案。
我们需要在这种方法中跟踪前一个节点。在每次递归调用中,我们使用当前节点数据检查先前的节点数据。如果当前节点数据小于先前,我们返回false
int isBST(node* root) {
static node* prev = NULL;
if(root==NULL)
return 1;
if(!isBST(root->left))
return 0;
if(prev!=NULL && root->data<=prev->data)
return 0;
prev = root;
return isBST(root->right);
}
答案 2 :(得分:1)
boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
if(node == null){
return true;
}
boolean left = isBinarySearchTree(node.getLeft(), min, node.getValue());
boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);
return left && right && (node.getValue()<max) && (node.getValue()>=min);
}
邀请评论。感谢。
答案 3 :(得分:0)
我认为第二种方法是正确的。树可以以递归方式遍历。在每次迭代时,可以存储当前子树的下限和上限。如果我们想用root x检查子树,并且子树的边界是l和h,那么我们所需要的只是检查l&lt; = x&lt; = h并检查带有边界l和x的左子树,并且正确的边界x和h。
这将具有O(n)复杂性,因为我们从根开始,并且每个节点仅作为某个子树的根检查一次。此外,我们需要O(h)内存用于递归调用,其中h是树的高度。
答案 4 :(得分:-1)
上面有一些使用INTEGER.MAX AND MIN的例子 我看不出有理由通过它们及其意义, 如果我错了,请纠正我或解释原因。
更多二进制搜索树可能包含通过compareTo方法或Coperator进行比较的对象..(因此Integer.MIN和Integer.MAX不适合该模型) 我正在编写一个返回true或false的代码 一个人必须调用(root_node,true),如果是bst,则返回true
void boolean isBSt( node root_node, boolean passed_root)
{
if ( node==null){
if ( passed_root)
return false;
// you have passed null pointer as
//root of the tree , since there is no
// valid start point we can throw an exception or return false
return true;
}
if( node.right !=null )
if ( node.right.data <= node.data)
return false;
if ( node.left !=null )
if ! ( node.left.data <= node.data)
return false;
return ( isBST( node.right , false) && isBST( node.left, false ) )
}
答案 5 :(得分:-1)
看看这个解决方案: http://preparefortechinterview.blogspot.com/2013/09/am-i-bst.html
它解释了不同的方法,并为您提供了一种通用且有效的方法。希望它有所帮助。
答案 6 :(得分:-2)
这是另一个解决方案,它使用2个辅助函数,使用辅助函数minValue和maxValue
为每个节点计算子树中的最小值和最大值int isBST(struct node* node)
{
if (node == NULL)
return(true);
/* false if the max of the left is > than us */
if (node->left!=NULL && maxValue(node->left) > node->data)
return(false);
/* false if the min of the right is <= than us */
if (node->right!=NULL && minValue(node->right) < node->data)
return(false);
/* false if, recursively, the left or right is not a BST */
if (!isBST(node->left) || !isBST(node->right))
return(false);
/* passing all that, it's a BST */
return(true);
}