剑指offer.C++.code61-67

2018-03-29  本文已影响0人  小异_Summer

61. 把二叉树打印成多行

// Solution:广度优先遍历,使用队列
/*
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>> res;
            if (pRoot == NULL)
                return res;
            vector<int> one_level;
            queue<TreeNode *> nodes;
            nodes.push(pRoot);
            int nextLevelToPrint = 0;
            int toBePrinted = 1;
            
            while (!nodes.empty()) {
                TreeNode * pNode = nodes.front();
                if (pNode->left != NULL) {
                    nodes.push(pNode->left);
                    nextLevelToPrint ++;
                }
                if (pNode->right != NULL) {
                    nodes.push(pNode->right);
                    nextLevelToPrint ++;
                }
                nodes.pop();
                one_level.push_back(pNode->val);
                toBePrinted --;
                if (toBePrinted == 0) {
                    res.push_back(one_level);
                    one_level.clear();
                    toBePrinted = nextLevelToPrint;
                    nextLevelToPrint = 0;
                }
            }
            return res;
        }
    
};

62. 序列化二叉树【没有理解透彻】

// Solution:流中读取,记录NULL
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    char* Serialize(TreeNode *root) {
        if (root == NULL)
            return NULL;
        string str;
        Serialize(root, str);
        char* res = new char[str.length()+1];
        int i;
        for (i = 0; i < str.length(); i ++)
            res[i] = str[i];
        res[i] = '\0';
        return res;
    }
    void Serialize(TreeNode *root, string& str) {
        if (root == NULL) {
            str += '#';
            return;
        }
        str += to_string(root->val);
        str += ',';
        Serialize(root->left, str);
        Serialize(root->right, str);
    }
    
    TreeNode * Deserialize(char *str) {
        if (str == NULL)
            return NULL;
        TreeNode * root = Deserialize(&str);
        return root;
    }
    TreeNode * Deserialize(char **str) {
        if (**str == '#') {
            (*str) ++;
            return NULL;
        }
        int num = 0;
        while (**str != '\0' && **str != ',') {
            num = num * 10 + ((**str)-'0');
            (*str) ++;
        }
        TreeNode * root = new TreeNode(num);
        if (**str == '\0')
            return root;
        else
            (*str) ++;
        root->left = Deserialize(str);
        root->right = Deserialize(str);
        return root;
    }
};

63. 二叉搜索树的第k个结点

//Solution:中序遍历,结点值递增
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    TreeNode* KthNodeCore(TreeNode* pRoot, int& k) {
        TreeNode* target = NULL;
        if (pRoot->left != NULL)
            target = KthNodeCore(pRoot->left, k);
        if (target == NULL) {
            if (k == 1)
                target = pRoot;
            k --;
        }
        if (target == NULL && pRoot->right != NULL)
            target = KthNodeCore(pRoot->right, k);
        return target;
    }
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if (pRoot == NULL || k == 0)
            return NULL;
        return KthNodeCore(pRoot, k);
    }
};

64. 流数据中的中位数

// Solution:使用最大堆、最小堆保存中位数相关的两个数
class Solution {
private:
    vector<int> min;
    vector<int> max;
public:
    void Insert(int num)
    {
        int size = min.size() + max.size();
        if ((size & 1) == 0) {    // 第奇数个值,放入最小堆中
            if (max.size() > 0 && num < max[0]) {    // 数字小于最大堆中最大值,需要保证最大堆中的值都小于最小堆中的值
                max.push_back(num);
                push_heap(max.begin(), max.end(), less<int>());
                num = max[0];
                pop_heap(max.begin(), max.end(), less<int>());
                max.pop_back();
            }
            min.push_back(num);
            push_heap(min.begin(), min.end(), greater<int>());
        } else {                                     // 第偶数个值,放入最大堆中
            if (min.size() > 0 && num > min[0]) {    // 数字大于最小堆中最小值,需要保证最小堆中的值都大于最大堆中的值
                min.push_back(num);
                push_heap(min.begin(), min.end(), greater<int>());
                num = min[0];
                pop_heap(min.begin(), min.end(), greater<int>());
                min.pop_back();
            }
            max.push_back(num);
            push_heap(max.begin(), max.end(), less<int>());
        }
    }

    double GetMedian()
    { 
        int size = max.size() + min.size();
        if (size == 0)
            return 0;
        double res = 0;
        if (size & 1 == 1) // 奇数个数字
            res = min[0];
        else               // 偶数个数字
            res = (min[0] + max[0]) / 2.0;
        return res;
    }

};

65. 滑动窗口的最大值

// Solution:使用双向队列,保存size大小的窗口中中最大值index
class Solution {
public:
    vector<int> res;
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        if (num.size() >= size && size >= 1) {
            deque<int> index;
            for (int i = 0; i < size; i ++) {
                while (!index.empty() && num[i] >= num[index.back()])
                    index.pop_back();
                index.push_back(i);
            }
            for (int i = size; i < num.size(); i ++) { //从index = size开始
                res.push_back(num[index.front()]);
                
                while (!index.empty() && num[i] >= num[index.back()])
                    index.pop_back();
                if (!index.empty() && index.front() <= (i - size))
                    index.pop_front();
                index.push_back(i);
            }
            res.push_back(num[index.front()]);
        }
        return res;
    }
};

66. 矩阵中的路径【回溯法】

//Solution:回溯法,同时标记已走过的路
class Solution {
public:
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        if (matrix == NULL || rows < 1 || cols < 1 || str == NULL)
            return false;
        bool *visited = new bool[rows*cols];
        memset(visited, 0, rows*cols);
        
        int pathLength = 0;
        for (int i = 0; i < rows; i ++) {
            for (int j = 0; j < cols; j ++) {
                if (hasPathCore(matrix, rows, cols, i, j, str, pathLength, visited)) {
                    return true;
                }
            }
        }
        delete [] visited;
        return false;
    }
    bool hasPathCore(char* matrix, int rows, int cols, int row, int col, char* str,
                     int pathLength, bool * visited) {
        if (str[pathLength] == '\0')
            return true;
        bool hasPath = false;
        if (row >= 0 && row < rows && col >= 0 && col < cols &&
           matrix[row * cols + col] == str[pathLength] &&
           visited[row * cols + col] == false) {
            
            pathLength ++;
            visited[row * cols + col] = true;
            hasPath = hasPathCore(matrix, rows, cols, row, col-1, str, pathLength, visited) ||
                hasPathCore(matrix, rows, cols, row-1, col, str, pathLength, visited) ||
                hasPathCore(matrix, rows, cols, row, col+1, str, pathLength, visited) ||
                hasPathCore(matrix, rows, cols, row+1, col, str, pathLength, visited);
            if (!hasPath) {
                pathLength --;
                visited[row * cols + col] = false;
            }
        }
        return hasPath;
    }

};

67. 机器人的运动范围【回溯法】

class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
        bool * visited = new bool[rows * cols];
        for (int i = 0; i < rows * cols; i ++)
            visited[i] = false;
        
        int count = movingCountCore(threshold, rows, cols, 0, 0, visited);
        delete [] visited;
        return count;
    }
    
    int movingCountCore(int threshold, int rows, int cols, int row, int col, bool * visited) {
        int count = 0;
        if (check(threshold, rows, cols, row, col, visited)) {
            visited[row * cols + col] = true;
            count = 1 + movingCountCore(threshold, rows, cols, row, col-1, visited) 
                + movingCountCore(threshold, rows, cols, row-1, col, visited)
                + movingCountCore(threshold, rows, cols, row, col+1, visited)
                + movingCountCore(threshold, rows, cols, row+1, col, visited);
        }
        return count;
    }
    
    bool check(int threshold, int rows, int cols, int row, int col, bool* visited){
        if (row >= 0 && row < rows && col >= 0 && col < cols &&
           !visited[row * cols + col] &&
           getDigitSum(row) + getDigitSum(col) <= threshold)
            return true;
        return false;
    }
    int getDigitSum(int num) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        return sum;
    }
};
上一篇 下一篇

猜你喜欢

热点阅读