leetcode_9:二叉樹

二叉樹的層次遍歷

給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。

給定二叉樹: [3,9,20,null,null,15,7],返回其層次遍歷結果:[[3],[9,20],[15,7]]。

思路: 二叉樹有四種形態,單節點,只有左子樹,或者只有右子樹,或者左右子樹都存在,所以需要把每一層的節點數目記錄下來。數據結構選擇隊列,先進先出。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> Q;
        vector<vector<int>> res;
        int index = 0;
        if(root){
            Q.push(root);
            index++;
        }
        while(!Q.empty()){
            vector<int> Array;
            int cnt = 0;
            while(index--){
                TreeNode* tmp = Q.front();
                Q.pop();
                Array.push_back(tmp->val);
                if(tmp->left) {
                    Q.push(tmp->left);
                    cnt++;
                }
                if(tmp->right){
                    Q.push(tmp->right);
                    cnt++;
                }
            }
            res.push_back(Array);
            index = cnt;
        }
        return res;
    }
};

二叉樹的中序遍歷

給定一個二叉樹,返回它的中序遍歷。

思路: 使用棧,先進後出

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> Array;
        stack<TreeNode*> s;
        TreeNode* current=root;
        while(current || !s.empty()){
            while(current){
                s.push(current);
                current = current->left;
            }
            current = s.top();
            s.pop();
            Array.push_back(current->val);
            current = current->right;
        }
        return Array;
    }
};

驗證二叉搜索樹

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

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

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

思路: 二叉搜索樹的中序遍歷是一個遞增的數列

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> S;
        int tmp= INT_MIN;
        int first = 0;
        while(!S.empty() || root){
            while(root){
                S.push(root);
                root = root->left;
            }
            root = S.top();
            S.pop();
            if(first&&root->val <= tmp){
                return false;
            }
            first++;
            tmp = root->val;
            root = root->right;
        }
        return true;
    }
};

從前序與中序遍歷序列構造二叉樹

根據一棵樹的前序遍歷與中序遍歷構造二叉樹。

注意:
你可以假設樹中沒有重複的元素。

思路: 前序遍歷的第一個元素一定是根節點,基於這個性質就可以把中序遍歷切分成兩部分,然後再對左半部分和右半部分進行上述迭代。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        int cnt = 0;
        return build(preorder, inorder, cnt, 0, n-1);
    }
    TreeNode* build(vector<int>&preorder, vector<int>& inorder, int& cnt, int left, int right){
        if(cnt==preorder.size()) return 0;
        //
        int index = 0;
        for(int i=left;i<=right;i++){
            if(inorder[i]==preorder[cnt]){
                index = i;
                break;
            }
        }
        TreeNode* node = new TreeNode(preorder[cnt]);
        if(left<index){
            cnt++;
            node->left = build(preorder, inorder, cnt, left, index-1);
        }
        if(index<right){
            cnt++;
            node->right = build(preorder, inorder, cnt, index+1, right);
        }
        return node;
    }
};

二叉樹的最近公共祖先

給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

百度百科中最近公共祖先的定義爲:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示爲一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”

說明:

  • 所有節點的值都是唯一的。
  • p、q 爲不同節點且均存在於給定的二叉樹中。

思路: 當節點p和q同在子樹時,公共節點爲兩個節點中深度最淺的那個;當節點p和q在不同子樹時。公共節點爲根節點。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==NULL || root==p || root==q){
            return root;
        }
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if(left && right) {
            return root;
        }
        else if(left){
            return left;
        }
        else if(right){
            return right;
        }
        return NULL;
    }
};

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/validate-binary-search-tree
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章