1. 程式人生 > 其它 >LeetCode98.驗證二叉搜尋樹

LeetCode98.驗證二叉搜尋樹

題目

給定一個二叉樹,判斷其是否是一個有效的二叉搜尋樹。

假設一個二叉搜尋樹具有如下特徵:

節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜尋樹。

示例1:

輸入:
 2
/ \
1   3
輸出: true

示例 2:

輸入:
5
/ \
1   4
/ \
3   6
輸出: false
解釋: 輸入為: [5,1,4,null,null,3,6]。
根節點的值為 5 ,但是其右子節點值為 4 。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/validate-binary-search-tree


著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解題思路

遞迴

如果該二叉樹的左子樹不為空,則左子樹上所有節點的值均小於它的根節點的值; 若它的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;它的左右子樹也為二叉搜尋樹。
時間複雜度 : O(n) 空間複雜度:O(n)

中序遍歷

二叉搜尋樹保證了左子樹的節點的值均小於根節點的值,根節點的值均小於右子樹的值,因此中序遍歷以後得到的序列一定是升序序列
時間複雜度 : O(n) 空間複雜度:O(n)

助解:假設現在有二叉樹    5
                      / \
                     3  6
先遍歷所有左節點,全部放入棧中 stack = [5,3]
遍歷完所有左節點後 從棧中取出 3 stack = [5]
判斷是否小於 變數inorder 用於儲存中序節點val
inorder初始化的值為min,所以不可能小 
inorder賦值3
把節點root=root.right(nil) 繼續下一次迴圈
root=3的節點沒有右節點,所以跳過壓入棧迴圈
再次從棧中pop節點 5 stack = []
判斷節點5(中節點)是否小於3(左節點),不小於說明符合有序二叉樹 
inorder賦值5
把節點root=root.right(6) 繼續下一次迴圈
節點6不為空,壓入棧中 stack = [6]
root = root.left 由於節點6沒有子節點了,進入下一步
把節點6從棧中取出 stack = []
判斷節點6(右節點)是否小於5(中節點),不小於說名符合有序二叉樹
把節點root=root.right(nil) 繼續下一次迴圈
棧為空,root為nil,不滿足最外層迴圈條件,程式結束 返回true

程式碼

type TreeNode struct {
  Val int
  Left *TreeNode
  Right *TreeNode
}

// 遞迴
func isValidBST(root *TreeNode) bool{
	return helper(root,math.MinInt64,math.MaxInt64)
}

func helper(root *TreeNode,lower,upper int) bool {
	// 遞迴到節點為空結束
	if root == nil{
		return true
	}
	// 左節點:如果左節點大於等於根節點 false
	// 右節點:如果右節點小於等於跟節點 false
	if root.Val <= lower || root.Val >= upper{
		return false
	}
	// 遞迴左右節點
	return helper(root.Left,lower,root.Val) && helper(root.Right,root.Val,upper)
}

// 中序遍歷
func isValidBST2(root *TreeNode) bool {
	// 棧儲存節點
	stack := []*TreeNode{}
	inorder := math.MinInt64
	// 當棧所有節點被取出 以及 節點為空時結束迴圈
	for len(stack) > 0 || root != nil{
		// 先把所有節點壓入棧
		for root != nil{
			stack = append(stack,root)
			root = root.Left
		}
		// pop棧,判斷是否符合有序二叉樹
		root = stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		if root.Val <= inorder{
			return false
		}
		// 儲存根節點值,切換到右子樹
		inorder = root.Val
		root = root.Right
	}
	return true
}