首页 > 代码库 > 剑桥offer(51~60)

剑桥offer(51~60)

51.题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
技术分享
/*
struct TreeLinkNode {
    int val;
    struct TreeLinkNode *left;
    struct TreeLinkNode *right;
    struct TreeLinkNode *next;
    TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
        
    }
};
*/
class Solution {

    TreeLinkNode* getNode(TreeLinkNode* pNode){
        TreeLinkNode*pre = NULL;
        while (pNode){
            pre = pNode;
            pNode = pNode->left;
        }
        return pre;
    }

public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        TreeLinkNode*tmp = pNode->next;
        if (tmp){//如果有父节点
            if (tmp->left == pNode&&pNode->right == NULL){//如果是左节点,就返回他的爸爸
                return tmp;
            }
            else if (tmp->left == pNode&&pNode->right != NULL){
                return getNode(pNode->right);
            }
            if (tmp->right == pNode){//如果是右节点,就返回他的右儿子
                if (pNode->right){
                    return getNode(pNode->right);
                }
                else if (tmp->next->left == tmp){
                    return tmp->next;
                }
                else if (tmp->next->right == tmp){
                    return NULL;
                }
            }
        }
        else{//根节点
            return getNode(pNode->right);
        }
        return NULL;
    }
};
View Code

52.题目描述

请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
技术分享
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot)
    {
        return isSymmetrical(pRoot,pRoot);
    }
     
    bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2)
    {
        if(pRoot1==NULL&&pRoot2==NULL)
            return true;
        if(pRoot1==NULL || pRoot2==NULL)           
            return false;
        if(pRoot1->val!=pRoot2->val)
            return false;
        return isSymmetrical(pRoot1->left,pRoot2->right) && isSymmetrical(pRoot1->right,pRoot2->left);
         
    }

};
View Code

53.题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
   不使用reverse!!! 借助两个stack,分别为s1和s2。
   1. 首先将根节点压入栈s1。
   2. 将s1依次出栈,保存每个节点值,并依次将每个节点的左右节点压入栈s2
   3. 将s2依次出栈,保存每个节点值,并依次将每个节点的右左节点压入本s1<注:这里是先压右子
      节点再压左子节点>
技术分享
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
         vector<vector<int> > result;
        if (!pRoot) { return result; }
        stack<TreeNode*> s1;
        stack<TreeNode*> s2;
        vector<int> temp;
        s1.push(pRoot);
        while (true) {
            while (!s1.empty()) {
                TreeNode* ptr = s1.top();
                s1.pop();
                if (!ptr) { continue; }
                s2.push(ptr->left);
                s2.push(ptr->right);
                temp.push_back(ptr->val);
            }
            if (temp.empty()) { break; }
            result.push_back(temp);
            temp.clear();
            while (!s2.empty()) {
                TreeNode* ptr = s2.top();
                s2.pop();
                if (!ptr) { continue; }
                s1.push(ptr->right);
                s1.push(ptr->left);
                temp.push_back(ptr->val);
            }
            if (temp.empty()) { break; }
            result.push_back(temp);
            temp.clear();
        }
        return result;
    }
        
    
    
};
View Code

54.题目描述

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
技术分享
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
        vector<vector<int> > Print(TreeNode* pRoot) {
            
            queue<TreeNode*>qu1;
            queue<TreeNode*>qu2;
            vector<int> a;
            vector<vector<int> >as;
            if(!pRoot)
                return as;
            qu1.push(pRoot);
            while(1){
                while(!qu1.empty()){
                   TreeNode*  tmp=qu1.front();
                    qu1.pop();
                    if(!tmp)continue;
                    a.push_back(tmp->val);
                    qu2.push(tmp->left);
                    qu2.push(tmp->right);
                }
                if(a.empty()){break;}
                as.push_back(a);
                a.clear();

                
                while(!qu2.empty()){
                   TreeNode*  tmp=qu2.front();
                    qu2.pop();
                    if(!tmp)continue;
                    a.push_back(tmp->val);
                    qu1.push(tmp->left);
                    qu1.push(tmp->right);
                }
                if(a.empty()){break;}
                as.push_back(a);
                a.clear();

            }
            return as;
        }
   
    
};
View Code

55.题目描述

请实现两个函数,分别用来序列化和反序列化二叉树
 
技术分享
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
private:
    TreeNode* decode(char *&str) {
        if(*str==#){
            str++;
            return NULL;
        }
        int num = 0;
        while(*str != ,)
            num = num*10 + (*(str++)-0);
        str++;
        TreeNode *root = new TreeNode(num);
        root->left = decode(str);
        root->right = decode(str);
        return root;
    }
public:
    char* Serialize(TreeNode *root) {    
        if(!root) return "#";
        string r = to_string(root->val);
        r.push_back(,);
        char *left = Serialize(root->left);
        char *right = Serialize(root->right);
        char *ret = new char[strlen(left) + strlen(right) + r.size()];
        strcpy(ret, r.c_str());
        strcat(ret, left);
        strcat(ret, right);
        return ret;
    }
    TreeNode* Deserialize(char *str) {
        return decode(str);
    }
};
View Code

56.题目描述

给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
 思路:中序遍历。
技术分享
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
    
    
    
public:
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        vector<TreeNode*>a;
        
        stack<TreeNode*>stack;
        TreeNode* p = pRoot;
        
        while(p || !stack.empty()){
            if(p!=NULL){
                stack.push(p);
                p = p->left;
            }else{
                p = stack.top();
                a.push_back(p);
                stack.pop();
                p = p ->right;
            }
        }
      
        if(k > a.size()){
            return NULL;
        }else if(k == 0){
            return NULL;
        }else{
            return a[k-1];
        }
    }

    
};
View Code

57.题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
技术分享
class Solution {
    vector<int>a;
public:
    void Insert(int num)
    {
        a.push_back(num);
    }
    double GetMedian()
    { 
        vector<int>b=a;
        sort(b.begin(), b.end());
        if(b.size()%2 == 1){
            return b[b.size()/2];
        }else{
            return (b[b.size()/2]+b[b.size()/2-1])/2.0;
        }
    }

};
View Code

58.题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
技术分享
class Solution {

    int getVal(vector<int>v){
        int max = v[0];
        for (int i = 0; i<v.size(); i++){
            if (max < v[i]){
                max = v[i];
            }
        }
        return max;
    }

public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int>a;
        vector<int>tmp;
        if (num.size()<size||size == 0)
            return a;
        for (int i = 0; i<num.size() - size+1; i++){
            for (int j = 0; j<size; j++){
                tmp.push_back(num[j + i]);
            }
            a.push_back(getVal(tmp));
    
            tmp.clear();
        }
        return a;
    }
};
View Code

59.题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
 
 
 

60.题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

剑桥offer(51~60)