二叉树力扣刷题(15)99. 恢复二叉搜索树100. 相同的树117. 填充每个节点的下一个右侧节点指针 II109. 有序链表转换二叉搜索树116. 填充每个

87 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

99. 恢复二叉搜索树

思路:

用三个新树,两个用来存储下次用来交换的结点,一个用来存储root后那个结点

代码:

class Solution {
public:
    TreeNode*fir = nullptr;
    TreeNode*sec = nullptr;
    TreeNode*pre = nullptr;

    void dfs(TreeNode*root) {
        if (root == nullptr) return;

        dfs(root->left);
        if (pre) {
            if (fir == nullptr && root->val <= pre->val) fir = pre;
            if (fir && root->val <= pre->val) sec = root;
        }
        pre = root;
        dfs(root->right);
    }
    void recoverTree(TreeNode* root) {
        dfs(root);
        int tmp = sec->val;
        sec->val = fir->val;
        fir->val = tmp;
    }
};

100. 相同的树

思路:

注意是结点的左右都符合条件即可

即return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
而不是 return isSameTree(p->left, q->left) || isSameTree(p->right, q->right);

代码:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (!p && q) return false;
        if (!q && p) return false;
        if (!q && !p) return true;
        if (p->val != q->val) return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
        

    }
};

109. 有序链表转换二叉搜索树

思路:

可以先将链表转为数组 或者 用快慢指针找出链表中间值,然后以中间值每次都构造树

代码:

class Solution {
public:

    ListNode* getmid (ListNode*left, ListNode*right) {
        ListNode*slow = left;
        ListNode*fast = left;
        while (fast != right && fast->next != right) {
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }

    TreeNode*gettree(ListNode*left, ListNode*right) {
        if (left == right) return nullptr;
        ListNode*mid = getmid(left, right);
        TreeNode*a = new TreeNode(mid->val);
        a->left = gettree(left, mid);
        a->right = gettree(mid->next, right);
        return a;
    }
    TreeNode* sortedListToBST(ListNode* head) {
        return gettree(head, nullptr);
    }
};

117. 填充每个节点的下一个右侧节点指针 II

思路:

层序遍历,连接即可

代码:

class Solution {
public:
    Node* connect(Node* root) {
        if(root == NULL) return root;
        queue<Node*> que;
        que.push(root);
        while (!que.empty()) {
            int size = que.size();
            Node* last = NULL;
            for (int i = 0; i < size; i++) {
                Node* top = que.front();
                que.pop();
                if (top->left) { que.push(top->left); }
                if (top->right) { que.push(top->right); }
                if (i != 0) { last->next = top;}                //让前一行的最后一个节点指向这行的第一个节点
                last = top;             //这行的结点连向后面的结点
            }
        }
        return root;
    }
};

116. 填充每个节点的下一个右侧节点指针

思路:

1.

递归

2.

与117思路一样

代码1:

class Solution {
public:
    Node* connect(Node* root) {
        if (root == NULL) return root;
        if (root->left) {
            root->left->next = root->right;
            if (root->next) {
                root->right->next = root->next->left;
            }
        }
        connect(root->left);
        connect(root->right);
        return root;
        
    }
};

代码2:

class Solution {
public:
    Node* connect(Node* root) {
        if(root == NULL) return root;
        queue<Node*> que;
        que.push(root);
        while (!que.empty()) {
            int size = que.size();
            Node* last = NULL;
            for (int i = 0; i < size; i++) {
                Node* top = que.front();
                que.pop();
                if (top->left) { que.push(top->left); }
                if (top->right) { que.push(top->right); }
                if (i != 0) { last->next = top;}                //如果pre为空就表示node节点是这一行的第一个,
                //没有前一个节点指向他,否则就让前一个节点指向他
                last = top;             //然后再让当前节点成为前一个节点
            }
        }
        return root;
    }
};

199. 二叉树的右视图

思路:

层序遍历找到que.size() - 1那个值即可

代码:

class Solution {
public:
    vector<int> ret;
    vector<int> rightSideView(TreeNode* root) {
        if (root == nullptr) return ret;

        queue<TreeNode*> que;
        que.push(root);
        while (!que.empty()) {
            int z = que.size();
            for (int i = 0; i < z; i++) {
                TreeNode* m = que.front();
                que.pop();
                if (i == z - 1) {
                    ret.push_back(m->val);
                }
                if (m->left) {
                    que.push(m->left);
                }
                if (m->right) {
                    que.push(m->right);
                }
            }
        }
        return ret;
    }
};