代码随想录刷题第15天

依然二叉树。没办法,二叉树实在太重要了。先学广度优先搜索在二叉树中的应用——层序遍历代码随想录。主要思想是用队列模拟,将每层元素数量用size记录,再通过while(size--)控制每层元素的弹出,最后将结果输入到一个二维数组中。下面进入实操环节,共有10道题。

第一题是层序遍历,手撕出了卡哥讲的方法。

class Solution {//层序遍历
public:
    vector> levelOrder(TreeNode* root) {
        queue que;
        vector> result;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            vector vec;
            while (size--) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

看代码随想录是发现还有递归法,比非递归的代码简洁了不少。

class Solution {
public:
    void order(TreeNode* cur, vector>& result, int depth) {
        if (cur == nullptr)
            return;
        if (result.size() == depth)
            result.push_back(vector());
        result[depth].push_back(cur->val);
        order(cur->left, result, depth + 1);
        order(cur->right, result, depth + 1);
    }
    vector> levelOrder(TreeNode* root) {
        vector> result;
        int depth = 0;
        order(root, result, depth);
        return result;
    }
};

有了以上代码基础,第二题https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/就很好写出,前面代码不变,result数组反转即可。

class Solution {
public:
    vector> levelOrderBottom(TreeNode* root) {
        queue que;
        vector> result;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            vector vec;
            while (size--) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            result.push_back(vec);
        }
        reverse(result.begin(), result.end());
        return result;
    }
};

第三题是二叉树的右视图https://leetcode.cn/problems/binary-tree-right-side-view/description/,只用记录层序遍历中最后一个元素,即size==0的情况,代码稍加修改即可。

class Solution {
public:
    vector rightSideView(TreeNode* root) {
        vector vec;
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            while (size--) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
                if (size == 0)
                    vec.push_back(node->val);
            }
        }
        return vec;
    }
};

第四题是二叉树的层平均值https://leetcode.cn/problems/average-of-levels-in-binary-tree/description/,也很简单。

class Solution {
public:
    vector averageOfLevels(TreeNode* root) {
        vector result;
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            double sum = 0;
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                sum += node->val;
                que.pop();
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            result.push_back(sum / size);
        }
        return result;
    }
};

第五题是n叉树的层序遍历https://leetcode.cn/problems/n-ary-tree-level-order-traversal/。

class Solution {
public:
    vector> levelOrder(Node* root) {
        vector> result;
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            vector vec;
            for (int i = 0; i < size; i++) {
                Node* node = que.front();
                vec.push_back(node->val);
                que.pop();
                for (int i = 0; i < node->children.size(); i++) {
                    if (node->children[i])
                        que.push(node->children[i]);
                }
            }
            result.push_back(vec);
        }
        return result;
    }
};

 第六题是每个树行找最大值https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/。

class Solution {
public:
    vector largestValues(TreeNode* root) {
        vector max;
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            int a = INT_MIN;
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                if (node->val > a)
                    a = node->val;
                que.pop();
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            max.push_back(a);
        }
        return max;
    }
};

第七题 是填充每个节点的下一个节点指针https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/description/。

class Solution {
public:
    Node* connect(Node* root) {
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            Node* nodepre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodepre = que.front();
                    que.pop();
                    node = nodepre;
                } else {
                    node = que.front();
                    que.pop();
                    nodepre->next = node;
                    nodepre = nodepre->next;
                }
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
                if (i == size - 1)
                    node->next = NULL;
            }
        }
        return root;
    }
};

第八题和第七题相同,只是情景设定一个是完美二叉树一个是不完美二叉树,层序遍历的逻辑不变。https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/description/

class Solution {
public:
    Node* connect(Node* root) {
        queue que;
        if(root != NULL) que.push(root);
        while(!que.empty()){
            int size = que.size();
            Node* nodepre;
            Node* node;
            for(int i = 0; i < size; i++){
                if(i == 0) {
                    nodepre = que.front();
                    que.pop();
                    node = nodepre;
                }
                else{
                    node = que.front();
                    que.pop();
                    nodepre->next = node;
                    nodepre = nodepre->next;
                }
                if (i == size - 1) node->next = NULL;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return root;
    }
};

第九题是二叉树的最大深度 https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/,只用定义一个depth变量,每次进入size循环前加一即可。

class Solution {
public:
    int maxDepth(TreeNode* root) {
        queue que;
        int depth = 0;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
            depth++;
        }
        return depth;
    }
};

第十题是二叉树的最小深度https://leetcode.cn/problems/minimum-depth-of-binary-tree/,如果层序遍历遇到叶子结点,跳出循环即可。

class Solution {
public:
    int minDepth(TreeNode* root) {
        int depth = 0;
        queue que;
        if (root != NULL)
            que.push(root);
        while (!que.empty()) {
            int size = que.size();
            depth++;
            while (size--) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left == NULL && node->right == NULL)
                    return depth;
                if (node->left)
                    que.push(node->left);
                if (node->right)
                    que.push(node->right);
            }
        }
        return depth;
    }
};

终于把这个层序遍历做完了,泪目了,头一次做这么多题。我要打十个!!!

第11题是翻转二叉树https://leetcode.cn/problems/invert-binary-tree/description/,有点做不动了,直接看卡哥讲解了。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
    if(root == NULL) return root;
    swap(root->left, root->right);
    invertTree(root->left);
    invertTree(root->right);
    return root;
    }
};

另外还有迭代法与层序遍历。

class Solution {//前序遍历迭代法
public:
    TreeNode* invertTree(TreeNode* root) {
    if(root == NULL) return root;
    stack st;
    st.push(root);
    while(!st.empty()){
        TreeNode* node = st.top();
        st.pop();
        swap(node->left, node->right);
        if(node->left) st.push(node->left);
        if(node->right) st.push(node->right);
    }
    return root;
    }
};
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
    queue que;
    if (root != NULL) que.push(root);
    while(!que.empty()){
        int size = que.size();
        while(size--){
            TreeNode* node = que.front();
            que.pop();
            swap(node->left, node->right);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
    }
    return root;
    }
};

最后一题对称二叉树https://leetcode.cn/problems/symmetric-tree/description/,重点是对称的判断与遍历的顺序。

class Solution {
public:
    bool compare(TreeNode* left, TreeNode* right) {
        if (left == NULL && right != NULL)
            return false;
        else if (left != NULL && right == NULL)
            return false;
        else if (left == NULL && right == NULL)
            return true;
        else if (left->val != right->val)
            return false;
        bool outside = compare(left->left, right->right);
        bool inside = compare(left->right, right->left);
        bool isSame = outside && inside;
        return isSame;
    }
    bool isSymmetric(TreeNode* root) {
        if (root == NULL)
            return true;
        return compare(root->left, root->right);
    }
};

连做十几题,累坏了哈哈,收获还是很大的,相信再遇到层序遍历就能直接手撕了。

你可能感兴趣的:(数据结构)