牛客网算法学习记录-二叉树2

来源:互联网 发布:淘宝助理app 编辑:程序博客网 时间:2024/06/07 09:47

首先我们介绍二叉树先序序列化的方式,假设序列化的结果字符串为str,初始时str等于空字符串。先序遍历二叉树,如果遇到空节点,就在str的末尾加上“#!”,“#”表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,“!”表示一个值的结束。如果遇到不为空的节点,假设节点值为3,就在str的末尾加上“3!”。现在请你实现树的先序序列化。

给定树的根结点root,请返回二叉树序列化后的字符串。

 

可以使用递归,也可使用非递归,但是非递归要注意与打印二叉树结点进行区分,就是对空结点的处理,访问的顺序没变。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

class TreeToString {
public:
    string toString(TreeNode* root) {
        // write code here
        TreeNode* cur;
        stack<TreeNode*> nodeStack;
        nodeStack.push(root);
        string result="";
        while(!nodeStack.empty()){
            cur = nodeStack.top();
            nodeStack.pop();
            if(cur !=NULL){
            int aa = cur->val;
   stringstream ss;
   ss<<aa;
            result = result+ss.str()+"!";
            }
            else{
                result = result+"#!";
                continue;
            }
            nodeStack.push(cur->right);
            nodeStack.push(cur->left);
        }
        return result;
    }
};

 

 平衡二叉树的检验:左右子树差值不超过1

有一棵二叉树,请设计一个算法判断这棵二叉树是否为平衡二叉树。

给定二叉树的根结点root,请返回一个bool值,代表这棵树是否为平衡二叉树。


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/


class CheckBalance {
public:
    bool check(TreeNode* root) {
        // write code here
        bool result = true;
        getHeight(root,1,result);
        return result;
    }
    
    int getHeight(TreeNode*root,int level ,bool &result){
        if(root == NULL){
            return level;
        }
        int lh = getHeight(root->left,level+1,result);
        if(!result)
            return level;
        int rh = getHeight(root->right,level+1,result);
        if(!result){
            return level;
        }
        if(lh-rh>1||rh-lh>1){
            result = false;
        }
        return max(lh,rh);
    }
    
};


有一棵二叉树,请设计一个算法判断它是否是完全二叉树。

给定二叉树的根结点root,请返回一个bool值代表它是否为完全二叉树。树的结点个数小于等于500。


主要检测两种错误,第一是存在右子树,但没有左子树,还有一种是,有左子树没又子树,那么该结点后面同层的结点都不能有子树,否则返回FALSE;

如果循环结束,返回true。

要注意先通过数组的形式按层记录下结点。

代码弄丢了= 。= 



请把纸条竖着放在桌⼦上,然后从纸条的下边向上⽅对折,压出折痕后再展 开。此时有1条折痕,突起的⽅向指向纸条的背⾯,这条折痕叫做“下”折痕 ;突起的⽅向指向纸条正⾯的折痕叫做“上”折痕。如果每次都从下边向上⽅ 对折,对折N次。请从上到下计算出所有折痕的⽅向。

给定折的次数n,请返回从上到下的折痕的数组,若为下折痕则对应元素为"down",若为上折痕则为"up".

测试样例:
1
返回:["down"]

每个结点的左子树为上 ,右子树为下


class FoldPaper {
public:
    vector<string> foldPaper(int n) {
        // write code here
        string down = "down";
        string up = "up";
        vector<string> result;
        bool isDown = true;
        if(n == 1){
            result.push_back(down);
            return result;
        }
        
        generateSerial(result,true,1,n);
        return result;
    }
    
    void generateSerial(vector<string> &vec,bool isDown,int level,int N){
        if(level>N)
            return;
        //模拟完全二叉树
        generateSerial(vec,true,level+1,N);
        if(isDown){
            vec.push_back("down");
        }
        else{
            vec.push_back("up");
        }
        generateSerial(vec,false,level+1,N);
    }
};


一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请找到这两个错误节点并返回他们的值。保证二叉树中结点的值各不相同。

给定一棵树的根结点,请返回两个调换了位置的值,其中小的值在前。


通过中序遍历进行访问tree,构建序列,搜索树的结点大于左子树的根小于右子树的根,所以如果本身序列无错,那么是升序。

分两种情况,第一种是只存在一个降序,那么肯定是第一次出现降序的两个临近的数放错:1,2,3,4,5 ->1,2,4,3,5

第二种是存在两个降序,第一次降序的第一个是本应该放在后面的大数,第二次降序是本应该放在前面的小数字,1,2,3,4,5->5,2,3,4,1


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/


class FindErrorNode {
public:
    vector<int> findError(TreeNode* root) {
        // write code here
        vector<int> result;
        vector<int> two;
        generateSerial(result,root);
        int index[2];
        
        int count = 0;
        for(int i = 0 ; i<result.size()-1;i++){
            if(result[i]>result[i+1]&&count==0){
                index[count++] = i;
            }
            else if(result[i]>result[i+1]&&count==1){
                index[count++] = i+1;
            }
        }
        if(count == 2){
            two.push_back(result[index[1]]);
            two.push_back(result[index[0]]);    
        }
        else if (count == 1){
            two.push_back(result[index[0]+1]);
            two.push_back(result[index[0]]);
        }
        return two;
    }
    
    void generateSerial(vector<int> &vec,TreeNode* root){
        
        if(root == NULL)
            return ;
        generateSerial(vec,root->left);
        vec.push_back(root->val);
        generateSerial(vec,root->right);
    }
};


别人家比较精简的代码:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
 
classFindErrorNode {
public:
    vector<int> findError(TreeNode* root) {
        // write code here
        vector<int> mid;
        get(root, mid);
        inta = -1, b = -1;
        for(inti = 1,lim = mid.size(); i < lim; ++i) {
            if(mid[i] < mid[i - 1]) {
                a = a == -1? mid[i-1] : a;
                b = mid[i];
            }
        }
        vector<int> res;
        res.push_back(b); res.push_back(a);
        returnres;
         
    }
    voidget(TreeNode* root, vector<int> &mid) {
        if(root->left) get(root->left, mid);
        mid.push_back(root->val);
        if(root->right) get(root->right, mid);
    }
};


7.13

从二叉树的节点A出发,可以向上或者向下走,但沿途的节点只能经过一次,当到达节点B时,路径上的节点数叫作A到B的距离。对于给定的一棵二叉树,求整棵树上节点间的最大距离。

给定一个二叉树的头结点root,请返回最大距离。保证点数大于等于2小于等于500.



7.14

有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.

给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。


0 0
原创粉丝点击