剑指OFFER61-66题

61序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树

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

        vector<int> buf;

    void dfs1(TreeNode *root){
        if(!root)
            buf.push_back(0xFFFFFFFF);
        else{
            buf.push_back(root->val);
            dfs1(root->left);
            dfs1(root->right);
        }
    }

    TreeNode* dfs2(int* &str){
        if(*str == 0xFFFFFFFF){
            ++str;
            return NULL;
        }
        TreeNode* res = new TreeNode(*str);
        str++;
        res->left = dfs2(str);
        res->right = dfs2(str);
        return res;
    }

    char* Serialize(TreeNode *root) {    
        buf.clear();
        dfs1(root);
        int bufSize = buf.size();
        int *res = new int[bufSize];
        for(int i = 0;i < bufSize; i++) res[i] = buf[i];
        return (char*)res;
    }
    TreeNode* Deserialize(char *str) {
        int *p = (int*)str;
        return dfs2(p);
    }
};

62二叉搜索树的第k个结点
题目描述
给定一棵二叉搜索树,请找出其中的第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* ans=NULL;
    int dfs(TreeNode* r,int k){
        if(r==NULL)return 0;//空就是没有结点
        int ln=dfs(r->left,k);//搜左儿得到左子树的结点数
        if(ln+1==k)ans=r;//左子树结点数+1是K则当前点就是答案了
        int lr=dfs(r->right,k-ln-1);//搜左儿得到右子树的结点数
        return ln+lr+1;//返回当前子树结点数
    }
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        int hhh=dfs(pRoot,k);
        return ans;
    }

    
};

63数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

class Solution {
public:
    vector<int> s;
    void Insert(int num)
    {
        if(s.empty()){//空
            s.push_back(num);
            return ;
        }
        if(num>s[s.size()-1]){//MAX
            s.push_back(num);
            return ;
        }
        s.push_back(s[s.size()-1]);//最大值后移
        for(int i=s.size()-2;i>=1;i--){//逐位判
            if(num>=s[i]){//大于当前位
                s[i+1]=num;//就赋在其右边
                return ;
            }
            s[i]=s[i-1];
        }
        //比1号位还要小,则要跟0号位比较
        if(num<=s[0])s[0]=num;//更小就在左边
        else s[1]=num;//否则在右边
    }

    double GetMedian()
    { 
        int len=s.size();
        if(len%2==1)return s[len/2];
        else return ((double)s[len/2]+(double)s[len/2-1])/2;
    }

};

64滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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 {
public:
    multiset<int> s;
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> ans;
        if(num.size()==0 || size==0 || num.size()<size)return ans;
        int len=num.size(),mx=num[0];
        for(int i=0;i<size;i++){
            s.insert(num[i]);
            mx=mx>num[i]?mx:num[i];
        }
        ans.push_back(mx);
        int l=0,r=size;
        for(int i=size;i<len;i++){
            s.erase(num[l++]);
            s.insert(num[r++]);
            multiset<int>::iterator ip = s.end();  // 返回指向最后一个元素的迭代器
            --ip;
            ans.push_back(*ip);
        }
        return ans;
    }
};

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

class Solution {
public:
    bool helper(char* matrix, int rows, int cols, int i, int j, char* str, int k, int* flag){
        int index = i * cols + j;
        if(i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1){
            //下标不符合,index对应的值不为和字符数组中的不一致,或者该index已经被访问,这些情况只要有符合的就返回false
            //只有上面的所有情况都不符合,也就是值相等,且没有访问过,下标不符合
            return false;
        }
        if(k == strlen(str) - 1){
            return true;
        }
        flag[index] = 1;
        if(helper(matrix, rows, cols, i - 1, j, str, k + 1, flag)
           ||helper(matrix, rows, cols, i + 1, j, str, k + 1, flag)
           ||helper(matrix, rows, cols, i, j - 1, str, k + 1, flag)
           ||helper(matrix, rows, cols, i , j + 1, str, k + 1, flag)){
            return true;
        }
        flag[index] = 0;
        return false;
    }
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        int* flag = new int[strlen(matrix)];
        for(int i = 0; i < rows; i ++){
            for(int j = 0; j < cols; j ++){
                if(helper(matrix, rows, cols, i, j, str, 0, flag)){
                    return true;
                }
            }
        }
        return false;
    }

};

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

class Solution {
public:
    typedef pair<int,int> p;
    int sum(int x){
        int ans=0;
        while(x>0){
            ans+=x%10;
            x/=10;
        }
        return ans;
    }
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    int movingCount(int threshold, int rows, int cols)
    {
        int vis[rows][cols];
        memset(vis,0,sizeof(vis));
        queue< p > qe;
        qe.push( p(0,0) );
        int ans=0;
        while(!qe.empty()){
            p tp=qe.front();
            qe.pop();
            ans++;
            for(int i=0;i<4;i++){
                int nx=tp.first+dx[i],ny=tp.second+dy[i];
                if( vis[nx][ny]==0 && sum(nx)+sum(ny)<=threshold && 0<=nx && nx<=rows && 0<=ny && ny<=cols ){
                    qe.push(p(nx,ny));
                    vis[nx][ny]=1;
                }
            }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/cj1064789374/article/details/85010869