題目
判斷一個(gè)二叉樹是否是一個(gè)有效的二叉搜索樹。(為與leetCode一致,假設(shè)所有節(jié)點(diǎn)的關(guān)鍵值不重復(fù))
解析
考察重點(diǎn):二叉搜索樹性質(zhì)
解題方法:
方法一:
中序遍歷。二叉搜索樹的中序遍歷結(jié)果是關(guān)鍵字有序的,如果結(jié)果中關(guān)鍵字并不是升序排列則不是二叉搜索樹。不需要記錄所有結(jié)果只需記錄當(dāng)前遍歷節(jié)點(diǎn)關(guān)鍵字和前一個(gè)節(jié)點(diǎn)關(guān)鍵字,比較兩者大小,如果不是升序排列即可斷定不是二叉搜索樹。
方法二:
遞歸方法。遞歸依次判斷每個(gè)節(jié)點(diǎn)是否滿足二叉搜索樹的性質(zhì),這里,當(dāng)前節(jié)點(diǎn)需要分別與它的左子樹的最右節(jié)點(diǎn)和右子樹的最左節(jié)點(diǎn)比較,觀察是否符合性質(zhì),如果符合性質(zhì)繼續(xù)校驗(yàn)其他節(jié)點(diǎn)。因?yàn)榧偃缬易訕涞淖钭蠊?jié)點(diǎn)不是當(dāng)前節(jié)點(diǎn)右子樹的最小節(jié)點(diǎn),雖然可以通過當(dāng)前節(jié)點(diǎn)的校驗(yàn),但是在之后校驗(yàn)右子樹其他節(jié)點(diǎn)時(shí)候會(huì)被發(fā)現(xiàn)不符合二叉搜索樹的性質(zhì)。
代碼
方法一:
public boolean isValidBST(TreeNode root) {
if(null == root){
return true;
}
int lastValue = 0;
//初始化標(biāo)記,如果是true,則初始化lastValue,否則比較lastValue判斷是否符合二叉搜索樹條件
boolean initial = true;
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
//迭代中序遍歷
while(node != null){
while(node != null){
stack.push(node);
node = node.left;
}
while(!stack.empty() && node == null){
node = stack.pop();
//初始化設(shè)置lastValue值
if(initial){
lastValue = node.val;
initial = false;
} else {//比較當(dāng)前節(jié)點(diǎn)與之前值大小,如果逆序則直接判斷不符合二叉搜索樹性質(zhì)
if(node.val <= lastValue){
return false;
} else {//更新lastValue值
lastValue = node.val;
}
}
node = node.right;
}
}
return true;
}
方法二:
public boolean isValidBST(TreeNode root) {
if(null == root){
return true;
}
//判斷當(dāng)前節(jié)點(diǎn)是否符合二叉搜索樹性質(zhì)
TreeNode right = minRightChild(root.right);
if(null != right && right.val <= root.val){
return false;
}
TreeNode left = maxLeftChild(root.left);
if(null != left && left.val >= root.val){
return false;
}
//遞歸判斷左右子樹
boolean r = isValidBST(root.right);
boolean l = isValidBST(root.left);
//左右子樹任一不滿足性質(zhì)則整棵樹不滿足性質(zhì)
return l && r;
}
//右子樹中最左節(jié)點(diǎn)
private TreeNode minRightChild(TreeNode right){
if(null == right){
return null;
}
while(right.left != null){
right = right.left;
}
return right;
}
//左子樹中最右節(jié)點(diǎn)
private TreeNode maxLeftChild(TreeNode left){
if(null == left){
return null;
}
while(left.right != null){
left = left.right;
}
return left;
}