判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60

题目描述
判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60_第1张图片

  • 二叉查找树BST(Binary Search Tree),(<=>二叉搜索树二叉排序树
    ①是一棵空树,
    ②或是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
  • 完全二叉树
    一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
法一)中序遍历(递归)+层次遍历
  • 解题思路
    判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60_第2张图片
    判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60_第3张图片
  • 复杂度分析
    该方法需要遍历两次树,因此时间复杂度为O(N);
    该方法定义了数组和队列分别用来进行中序遍历和层次遍历,因此空间复杂度为O(N)。
  • 代码如下
class Solution {
public:
    vector<bool> judgeIt(TreeNode* root) {
        vector<bool> res(2, false);
        if(!root){
            res[0] = true;
            res[1] = true;
            return res;
        }
        vector<int> inorderRes;
        inorder(root, inorderRes); //中序遍历
        res[0] = true;
        //判断中序遍历结果是否升序
        for(int i=0; i<inorderRes.size()-1; ++i){
            if(inorderRes[i]>inorderRes[i+1]){
                res[0] = false;
                break;
            }
        }
        //层次遍历
        res[1] = levelOrder(root);
        return res;
    }

    void inorder(TreeNode* root, vector<int>& inorderRes){
        if(!root) return;
        inorder(root->left, inorderRes);
        inorderRes.push_back(root->val);
        inorder(root->right, inorderRes);
    }
    bool levelOrder(TreeNode* root){
        queue<TreeNode*> q;
        q.push(root);
        while(q.front()){
            TreeNode* tmp = q.front();
            q.pop();
            q.push(tmp->left);
            q.push(tmp->right);
        }
        while(q.size() && !q.front()){
            q.pop();
        }
        return q.empty();
    }
};

// class Solution {
// public:
//     vector sort; //记录二叉树的中序遍历是否有序
//     void judgeSBT(TreeNode* root){ //判断是否为搜索二叉树:递归中序遍历
//         TreeNode* head = root;
//         if(head == NULL)
//             return;
//         judgeSBT(head->left);
//         sort.push_back(head->val);
//         judgeSBT(head->right);
//     }
//     bool judgeCBT(TreeNode* root){ //判断是否为完全二叉树:层次遍历
//         TreeNode* head = root;
//         if(head == NULL) 
//             return true; //如果是空,则一定是完全二叉树
//         queue temp; //队列存储,进行层次遍历
//         temp.push(head); 
//         TreeNode* p;
//         bool flag = false; //记录是否开始出现叶子结点
//         while(!temp.empty()){
//             p = temp.front();
//             temp.pop();
//             if(p == NULL) {//如果是空,说明其后面都没有孩子了
//                 flag= true;
//                 continue;
//             }
//             if(flag) 
//                 return false;//如果是true,说明前面出现过叶子结点
//             //存入左右孩子作为下一个层次
//             temp.push(p->left);
//             temp.push(p->right);
//         }
//         return true;
//     }
//     vector judgeIt(TreeNode* root) {
//         vector res;
//         judgeSBT(root);
//         bool flag = true;
//         for(int i = 1; i < sort.size(); i++){  //检查是否为递增序列
//             if(sort[i - 1] > sort[i])
//                 flag = false;
//         }
//         res.push_back(flag);
//         res.push_back(judgeCBT(root));
//         return res;
//     }
// };
法二)中序遍历(非递归)+层次遍历优化
  • 解题思路
    判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60_第4张图片
    判断一棵二叉树是否为搜索二叉树和完全二叉树——牛客NC60_第5张图片
  • 复杂度分析
    该方法需要遍历两次树,因此时间复杂度为O(N);
    该方法定义了栈和队列分别用来进行中序遍历和层次遍历,因此空间复杂度为O(N)。
  • 代码如下
class Solution{
public:
    vector<bool> judgeIt(TreeNode* root){
        vector<bool> res(2);
        if(!root){
            res[0] = true;
            res[1] = true;
            return res;
        }
        //定义栈  中序遍历
        stack<TreeNode*> s;
        TreeNode* p = root;
        int min_ = INT_MIN;
        res[0] = true;
        while(p || s.size()){
            while(p){
                s.push(p);
                p = p->left;
            }
            if(s.size()){
                p = s.top();
                //判断是否严格递增
                if(min_ < p->val){
                    min_ = p->val;
                } else{
                    res[0] = false;
                    break;
                }
                s.pop();
                p = p->right;
            }           
        }
        //定义队列层次遍历
        queue<TreeNode*> q;
        bool flag = false;
        res[1] = true;
        q.push(root);
        while(q.size()){
            TreeNode* tmp =  q.front();
            q.pop();
            //遇到空节点 flag置为true
            if(!tmp){
                flag = true;
                continue;
            } else{
                //遇到非空节点
                if(flag){
                    res[1] = false;
                    break;
                } else{ //flag仍为false时,继续遍历
                    q.push(tmp->left);
                    q.push(tmp->right);
                }
            }
        }
        return res;
    }
};

// class Solution {
// public:
//     vector sort; //记录二叉树的中序遍历是否有序
//     void judgeSBT(TreeNode* root){ //判断是否为搜索二叉树:递归中序遍历
//         stack s; //设置栈用于遍历
//         TreeNode* head = root;
//         while (head != NULL || !s.empty()) {
//             while (head != NULL) {   //直到没有左节点
//                 s.push(head);
//                 head = head->left;
//             }
//             head = s.top();
//             s.pop();
//             sort.push_back(head->val);//访问节点
//             head = head->right;
//         }
//     }
//     bool judgeCBT(TreeNode* root){ //判断是否为完全二叉树:层次遍历
//         TreeNode* head = root;
//         if(head == NULL) 
//             return true; //如果是空,则一定是完全二叉树
//         queue temp; //队列存储,进行层次遍历
//         temp.push(head); 
//         TreeNode* p;
//         bool flag = false; //记录是否开始出现叶子结点
//         while(!temp.empty()){
//             p = temp.front();
//             temp.pop();
//             if(p == NULL) {//如果是空,说明其后面都没有孩子了
//                 flag= true;
//                 continue;
//             }
//             if(flag) 
//                 return false;//如果是true,说明前面出现过叶子结点
//             //存入左右孩子作为下一个层次
//             temp.push(p->left);
//             temp.push(p->right);
//         }
//         return true;
//     }
//     vector judgeIt(TreeNode* root) {
//         vector res;
//         judgeSBT(root);
//         bool flag = true;
//         for(int i = 1; i < sort.size(); i++){
//             if(sort[i - 1] > sort[i])
//                 flag = false;
//         }
//         res.push_back(flag);
//         res.push_back(judgeCBT(root));
//         return res;
//     }
// };

你可能感兴趣的:(leetcode,算法,数据结构,leetcode)