LeetCode98. 驗證二叉搜尋樹

Tomorrowland_D發表於2024-07-29

題目連結:https://leetcode.cn/problems/validate-binary-search-tree/description/

題目敘述:

給你一個二叉樹的根節點 root ,判斷其是否是一個有效的二叉搜尋樹。

有效二叉搜尋樹定義如下:

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

示例 1:

輸入:root = [2,1,3]
輸出:true

示例 2:


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

提示:

樹中節點數目範圍在[1, 10^4] 內
-2^31 <= Node.val <= 2^31 - 1

思路:

二叉搜尋樹是一顆有序的樹,我們可以利用這個很有用的性質

我們知道二叉樹的每個結點,它的左子樹上的所有結點都小於這個結點,它的右子樹上的所有結點都大於這個結點

那麼我們使用中序遍歷,將這個二叉搜尋樹中的元素全部存取到陣列中,這個陣列就是有序的了(如果是二叉搜尋樹的話)

那麼現在我們就轉化成了判斷一個陣列的序列是否有序了

程式碼:

class Solution {
public:
	void traversal(TreeNode* root, vector<int>& vec) {
		if (root == NULL) return;
		//處理左子樹
		traversal(root->left, vec);
		//處理中的邏輯
		vec.push_back(root->val);
		//處理右子樹
		traversal(root->right, vec);
	}
	bool isValidBST(TreeNode* root) {
		vector<int> vec;
		traversal(root, vec);
		for (int i = 1; i < vec.size(); i++) {
			//找到了無序的序列,就直接返回false
			if (vec[i] <= vec[i - 1]) return false;
		}
		//否則,返回true
		return true;
	}
};

另一種方法

其實,這題我們可以不使用陣列來記錄所有的結點,可以使用一個指標,用來記錄上一個訪問過的結點,然後比較上一個結點和當前結點的大小,如果不同,就直接返回false,相同則

呼叫遞迴函式比較左右子樹,如果左右子樹有一個為false,則為false,否則就是true

程式碼

class Solution {
public:
    TreeNode*pre=NULL;
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true;
        //遞迴處理左子樹
        int left=isValidBST(root->left);
        //如果上一個結點大於當前結點,返回false
        if(pre!=NULL&&pre->val>=root->val) return false;
        //更新pre的值
        pre=root;
        int right=isValidBST(root->right);
        //left和right有一個為假,就是假
        return left&&right;
    }
};

迭代法

這題迭代法的程式碼與第二種的思路很像,也是使用一個指標來儲存上一個結點的值

迭代法程式碼:

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true;
        stack<TreeNode*> st;
        TreeNode*pre=NULL;
        TreeNode*cur=root;
        while(!st.empty()||cur!=NULL){
            if(cur!=NULL){
                st.push(cur);
                cur=cur->left;
            }
            else{
                cur=st.top();
                st.pop();
            //找到比上一個結點大的結點,直接返回false
                if(pre!=NULL&&pre->val>=cur->val) return false;
                pre=cur;
                cur=cur->right; 
            }
        }
        return true;
    }
};

相關文章