LeetCode【代码随想录】刷题(二叉树篇)

节点定义如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

226.翻转二叉树

力扣题目链接

题目:给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。

思路:简单递归

通过代码:

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

101. 对称二叉树

力扣题目链接

题目:给你一个二叉树的根节点root , 检查它是否轴对称。

思路:递归和迭代都可以,关键是要认清比较对象。左孩子的左孩子和右孩子的右孩子比,左孩子的右孩子和右孩子的左孩子比。

通过代码:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(!root)
            return true;
        queue<TreeNode*> q;
        q.push(root -> left);
        q.push(root -> right);
        while(!q.empty())
        {
            TreeNode *left = q.front(); q.pop();
            TreeNode *right = q.front(); q.pop();
            if(!left && !right)
                continue;
            if(left && !right || !left && right || left -> val != right -> val)
                return false;
            q.push(left -> left);
            q.push(right -> right);
            q.push(left -> right);
            q.push(right -> left);
        }
        return true;
    }
};

104.二叉树的最大深度

力扣题目链接

题目:给定一个二叉树root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

思路一:递归,深度为左右子树中较大的深度+1。

通过代码:

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root)
            return 0;
        return max(maxDepth(root -> left), maxDepth(root -> right)) + 1;
    }
};

思路二:层序遍历的时候记录深度。

111.二叉树的最小深度

力扣题目链接

题目:给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

思路:层序遍历(也就是宽搜)的时候记录深度,遇到第一个叶子节点的时候就是最小深度。

通过代码:

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

222.完全二叉树的节点个数

力扣题目链接

题目:给你一棵完全二叉树的根节点 root ,求出该树的节点个数。

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第h层,则该层包含1~ 2^h个节点。

思路:直接递归遍历一个个数是可以的,但是太慢,没有用到完全二叉树的性质。可以优化一下。观察能发现,完全二叉树的子树是包含满二叉树的。而满二叉树的节点数根据层数可以用公式直接算出来:$ 2^{层数}-1 $。在一个完全二叉树里判断满二叉树,只要最左边和最右边向下迭代得到的层数相等就是满二叉树。

通过代码:

class Solution {
public:
    int countNodes(TreeNode* root) {
        if(!root)
            return 0;
        // 以下是优化部分,没有这部分也能过
        int depth_left = 0, depth_right = 0;
        TreeNode *left = root, *right = root;
        while(left)
        {
            depth_left++;
            left = left -> left;
        }
        while(right)
        {
            depth_right++;
            right = right -> right;
        }
        if(depth_left == depth_right)
            return pow(2, depth_left) - 1;
        // 以上是优化部分
        return countNodes(root -> left) + countNodes(root -> right) + 1;
    }
};

110.平衡二叉树

力扣题目链接

题目:给定一个二叉树,判断它是否是 平衡二叉树。

思路:递归,左右子树是平衡的,并且左右子树高度差不超过1。所以需要一个函数来求高度。104.二叉树的最大深度这道题已经解决了,用一个小递归求得高度,再在判断平衡时递归一下即可。但是这样写求高度的时候遍历了一遍树,判断平衡的时候又遍历了一遍,重复了。所以完全可以合在一起,在求高度的时候就可以判断是否平衡了。不平衡直接返回-1,平衡的时候再正常求高度。

通过代码:

class Solution {
public:
    int height(TreeNode *root){
        if(!root)
            return 0;
        int left_height = height(root -> left);
        int right_height = height(root -> right);
        if(left_height == -1 || right_height == -1 || abs(left_height - right_height) > 1)
            return -1;
        return max(left_height, right_height) + 1;
    }

    bool isBalanced(TreeNode* root) {
        return height(root) >= 0;
    }
};

257. 二叉树的所有路径

力扣题目链接

题目:给你一个二叉树的根节点root ,按任意顺序,返回所有从根节点到叶子节点的路径。叶子节点是指没有子节点的节点。

思路一:递归+回溯,path记录路径,res保存结果。如果左右孩子都为空,说明到叶子节点了,res保存一下path后返回。回溯体现在,path没有加引用,是按值传递。return回去之后,path还是上一层的值,可以继续换右孩子进行遍历。

通过代码:

class Solution {
public:
    void traverse(TreeNode *root, string path, vector<string> &res){
        path += to_string(root -> val);
        if(!root -> left && !root -> right)
        {
            res.push_back(path);
            return;
        }
        if(root -> left)
            traverse(root -> left, path + "->", res);
        if(root -> right)
            traverse(root -> right, path + "->", res);
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        string path;
        traverse(root, path, res);
        return res;
    }
};

思路二:宽搜,层序遍历。

通过代码:

class Solution {
public:

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        queue<TreeNode*> q_tree;
        queue<string> q_path;
        if(root)
        {
            q_tree.push(root);
            q_path.push(to_string(root -> val));
        }
        while(!q_tree.empty())
        {
            TreeNode *node = q_tree.front(); q_tree.pop();
            string path = q_path.front(); q_path.pop();
            if(!node -> left && !node -> right)
                res.push_back(path);
            if(node -> left)
            {
                q_tree.push(node -> left);
                q_path.push(path + "->" + to_string(node -> left -> val));
            }
            if(node -> right)
            {
                q_tree.push(node -> right);
                q_path.push(path + "->" + to_string(node -> right -> val));
            }
        }
        return res;
    }
};

404.左叶子之和

力扣题目链接

题目:给定二叉树的根节点root ,返回所有左叶子之和。

思路:深搜,类似前序遍历

通过代码:

class Solution {
public:
    void traverse(TreeNode *root, int &s){
        if(!root)
            return;
        if(root -> left && !root -> left ->left && !root -> left -> right)
            s += root -> left -> val;
        traverse(root -> left, s);
        traverse(root -> right, s);
    }

    int sumOfLeftLeaves(TreeNode* root) {
        int s = 0;
        traverse(root, s);
        return s;
    }
};

513.找树左下角的值

力扣题目链接

题目:给定一个二叉树的根节点root,请找出该二叉树的最底层 最左边节点的值。

假设二叉树中至少有一个节点。

思路一:用两个变量保存当前找到的值和深度。其实找最深的节点就行了,不管是哪种遍历,左都在右前面遍历到,先遇到的一定是左,保存下来的也就是最左边的。

通过代码:

class Solution {
public:
    int val, depth = -1;
    void traverse(TreeNode *root, int d){
        if(!root)
            return;
        if(!root -> left && !root -> right)
        {
            if(d > depth)
            {
                val = root -> val;
                depth = d;
            }
        }
        traverse(root -> left, d + 1);
        traverse(root -> right, d + 1);
    }

    int findBottomLeftValue(TreeNode* root) {
        traverse(root, 1);
        return val;
    }
};

思路二:宽搜,层序遍历,很简单。

112. 路径总和

力扣题目链接

题目:给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

叶子节点 是指没有子节点的节点。

思路:递归,首先得找到任务分解的思路。从根节点开始找和等于sum,可以分解位从根节点的两个孩子开始找和等于sum - root->val。最后确定一下递归边界,即到叶节点的时候只要判断sum和自己的val是否相等即可。

通过代码:

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(!root)
            return false;
        if(!root -> left && !root -> right && root -> val == targetSum)
            return true;
        return hasPathSum(root -> left, targetSum - root ->val) || hasPathSum(root -> right, targetSum - root -> val);

    }
};

106.从中序与后序遍历序列构造二叉树

力扣题目链接

题目:给定两个整数数组inorderpostorder ,其中inorder是二叉树的中序遍历,postorder是同一棵树的后序遍历,请你构造并返回这颗二叉树 。

思路:通过后序数组的最后一个可以找到根节点。在前序数组中遍历找到根节点的位置,根节点左边为左子树,根节点右边为右子树。根据切割出的左右子数组的长度,在后序数组里同样能切出左右子树。递归找到左右子树的根节点即可。

通过代码:

class Solution {
public:
    TreeNode *traverse(vector<int> &inorder, int in_begin, int in_end, vector<int> &postorder, int post_begin, int post_end){
        if(post_end - post_begin == 0)
            return nullptr;
        int root_value = postorder[post_end - 1];
        TreeNode *root = new TreeNode(root_value);

        if(post_end - post_begin == 1)
            return root;

        int i;
        for(i = in_begin; i < in_end; i++)
            if(inorder[i] == root_value)
                break;
        
        int len_left = i - in_begin;
        int post_left_end = post_begin + len_left;
        int post_right_begin = post_left_end;
        int post_right_end = post_end - 1;

        root -> left = traverse(inorder, in_begin, i, postorder, post_begin, post_left_end);
        root -> right = traverse(inorder, i + 1, in_end, postorder, post_right_begin, post_right_end);
        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size() == 0 || postorder.size() == 0)
            return nullptr;
        return traverse(inorder, 0, inorder.size(), postorder, 0, postorder.size());
    }
};

654.最大二叉树

力扣题目地址

题目:给定一个不重复的整数数组nums最大二叉树可以用下面的算法从nums递归地构建:

  1. 创建一个根节点,其值为nums中的最大值。
  2. 递归地在最大值 左边 的 子数组前缀上 构建左子树。
  3. 递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回nums构建的最大二叉树 。

思路:有点类似上面那道题,不过简单一点。根据题目意思构建递归过程即可。

通过代码:

class Solution {
public:
    TreeNode *dfs(vector<int> &nums, int begin, int end){
        if(end - begin == 0)
            return nullptr;
        int idx = begin, max_val = nums[begin];
        for(int i = begin + 1; i < end; i++)
        {
            if(nums[i] > nums[idx])
            {
                idx = i;
                max_val = nums[i];
            }
        }
        TreeNode *root = new TreeNode(max_val);
        root -> left = dfs(nums, begin, idx);
        root -> right = dfs(nums, idx + 1, end);
        return root;
    }

    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        if(nums.size() == 0)
            return nullptr;
        return dfs(nums, 0, nums.size());
    }
};

617.合并二叉树

力扣题目链接

题目:给你两棵二叉树: root1root2

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

思路:递归同时遍历两个树,当两个根节点都不为空时,借用root1为新的节点,把root2的值加进去。然后递归得到合并后的左(右)子树根节点并赋值。

通过代码:

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(!root1)
            return root2;
        if(!root2)
            return root1;
        root1 -> val += root2 -> val;
        root1 -> left = mergeTrees(root1 -> left, root2 -> left);
        root1 -> right = mergeTrees(root1 -> right, root2 -> right);
        return root1;
    }
};

700.二叉搜索树中的搜索

力扣题目地址

题目:给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null

思路:迭代即可

通过代码:

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {            
        TreeNode *node = root;
        while(node)
        {
            if(node -> val == val)
                return node;
            else if(node -> val < val)
                node = node -> right;
            else
                node = node -> left;
        }
        return nullptr;
    }
};

98.验证二叉搜索树

力扣题目链接

题目:给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

思路:中序遍历二叉搜索树应该是递增的,所以中序遍历的时候当前节点的值大于前一个节点即可。

通过代码:

class Solution {
public:
    TreeNode *pre;
    bool isValidBST(TreeNode* root) {
        if(!root)
            return true;
        bool left = isValidBST(root -> left);
        if(pre && pre -> val >= root -> val)
            return false;
        pre = root;
        bool right = isValidBST(root -> right);
        return left && right;
    }
};

530.二叉搜索树的最小绝对差

力扣题目链接

题目:给你一个二叉搜索树的根节点 root ,返回树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。

思路:利用二叉搜索树的性值,中序遍历二叉搜索树是一个递增序列,因此只要比较相邻的节点即可。类似上面那道题,用一个pre记录前一节点即可。

通过代码:

class Solution {
public:
    TreeNode *pre = nullptr;
    int res = INT_MAX;

    void traverse(TreeNode *root){
        if(!root)
            return;
        traverse(root -> left);
        if(pre)
            res = min(res, abs(root -> val - pre -> val));
        pre = root;
        traverse(root -> right);
    }

    int getMinimumDifference(TreeNode* root) {
        traverse(root);
        return res;
    }
};

501.二叉搜索树中的众数

力扣题目链接

题目:给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按任意顺序返回。

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

思路:如果这不是二叉搜索树,就需要遍历所有节点统计次数并排序。但这是二叉搜索树,可以利用其中序遍历递增的特性。中序遍历时,值相同的节点一定连在一起,于是可以统计相同节点的次数并记录最大次数,若有和最大次数相同的,加入结果集;若比最大次数还大,更新最大次数、清空结果集、将新节点加入结果集。

通过代码:

class Solution {
public:
    TreeNode *pre = nullptr;
    int count = 0, maxcount = 0;
    vector<int> res;

    void traverse(TreeNode *root){
        if(!root)
            return;
        traverse(root -> left);
        if(!pre)
            count = 1;
        else if(root -> val == pre -> val)
            count++;
        else
            count = 1;
        pre = root;

        if(count == maxcount)
            res.push_back(root -> val);
        else if(count > maxcount)
        {
            maxcount = count;
            res.clear();
            res.push_back(root -> val);
        }
        traverse(root -> right);
    }

    vector<int> findMode(TreeNode* root) {
        traverse(root);
        return res;
    }
};

236. 二叉树的最近公共祖先

力扣题目链接

题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

思路:从下往上找,符合后序遍历。如果当前根节点为空或者正好等于指定节点,直接返回当前根节点。因为当前节点等于指定节点的话,没有必要再往下递归下去了,即便子树中有另一个指定节点,要返回的公共祖先还是当前节点。如果子树中没有另一个指定节点,就应该把当前节点传递上去。递归调用找到左右子树的公共祖先,如果都不为空,说明两个目标节点就在这两个子树中,最低公共祖先就是当前根节点;如果只有一个不为空,说明此时要么公共祖先已经找到了,该把答案返回去了;要么还有一个目标节点在上层,要返回上去汇合。

通过代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root || root == p || root == q)
            return root;
        TreeNode *left = lowestCommonAncestor(root -> left, p, q);
        TreeNode *right = lowestCommonAncestor(root -> right, p, q);
        if(left && right)
            return root;
        else if(!left)
            return right;
        return left;
    }
};

235. 二叉搜索树的最近公共祖先

力扣题目链接

题目:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

思路:本题和上一题的区别就在于二叉搜索树。结合二叉搜索树的性质,最近公共祖先的大小一定是位于两个节点之间的。因此,从上往下遍历即可。

通过代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root -> val > p -> val && root -> val > q -> val)
            return lowestCommonAncestor(root -> left, p, q);
        else if(root -> val < p -> val && root -> val < q -> val)
            return lowestCommonAncestor(root -> right, p, q);
        else
            return root;
    }
};

701.二叉搜索树中的插入操作

力扣题目链接

题目:给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

思路:简单递归。注意递归要返回根节点,回到上一层用left或right接住。

通过代码:

class Solution {
public:

    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(!root)
        {
            root = new TreeNode(val);
            return root;
        }
        if(val < root -> val)
            root -> left = insertIntoBST(root -> left, val);
        if(val > root -> val)
            root -> right = insertIntoBST(root -> right, val);
        return root;
    }
};

450.删除二叉搜索树中的节点

力扣题目链接

题目:给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

思路:找目标节点很容易,关键是删除节点要保持二叉搜索树的性质。找到目标节点后要考虑几种情况:

  1. 目标节点是叶节点,此时最容易,直接删除即可,不会影响什么;
  2. 目标节点左或右子树有一个为空,删除目标节点后,需要把不为空右或左子树提上来,返回的时候返回对应的节点地址即可。
  3. 目标节点左右子树都不为空,此时比较麻烦。由于目标节点比左子树大,比右子树小。所以删除之后需要把左子树最大的或右子树最小的提上来。这里选右子树最小的。右子树最小的只要一直往左下迭代就能找到。找到之后交换目标节点和右子树最小的节点的值。这样目标节点就到右子树去了,然后以右子树为根节点递归删除key即可。

通过代码:

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(!root)
            return root;
        if(root -> val == key)
        {
            if(!root -> left && !root -> right)
            {
                delete root;
                return nullptr;
            }
            else if(!root -> left)
            {
                TreeNode *node = root -> right;
                delete root;
                return node;
            }
            else if(!root -> right)
            {
                TreeNode *node = root -> left;
                delete root;
                return node;
            }
            else
            {
                TreeNode *node = root -> right;
                while(node -> left)
                    node = node -> left;
                swap(root -> val, node -> val);
                root -> right = deleteNode(root -> right, key);
                return root;
            }
        }
        if(key < root -> val)
            root -> left = deleteNode(root -> left, key);
        if(key > root -> val)
            root -> right = deleteNode(root -> right, key);
        return root;
    }
};

669. 修剪二叉搜索树

力扣题目链接

题目:给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

思路:对于当前访问的结点,如果结点为空结点,直接返回空结点;如果结点的值小于 low,那么说明该结点及它的左子树都不符合要求,我们返回对它的右结点进行修剪后的结果;如果结点的值大于 high,那么说明该结点及它的右子树都不符合要求,我们返回对它的左子树进行修剪后的结果;如果结点的值位于区间 [low,high],我们将结点的左结点设为对它的左子树修剪后的结果,右结点设为对它的右子树进行修剪后的结果。

通过代码:

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(!root)
            return nullptr;
        if(root -> val > high)
            return trimBST(root -> left, low, high);
        if(root -> val < low)
            return trimBST(root -> right, low, high);
        root -> left = trimBST(root -> left, low, high);
        root -> right = trimBST(root -> right, low, high);
        return root;
    }
};

108.将有序数组转换为二叉搜索树

力扣题目链接

题目:给你一个整数数组 nums ,其中元素已经按升序排列,请你将其转换为一棵平衡二叉搜索树。

思路:每次都取中间的值作为根节点即可,简单递归一下。

通过代码:

class Solution {
public:
    TreeNode* construct(vector<int> &nums, int low, int high){
        if(high < low)
            return nullptr;
        int mid = (low + high) / 2;
        TreeNode *root = new TreeNode(nums[mid]);
        root -> left = construct(nums, low, mid - 1);
        root -> right = construct(nums, mid + 1, high);
        return root;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return construct(nums, 0, nums.size() - 1);
    }
};

538.把二叉搜索树转换为累加树

力扣题目链接

题目:给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

思路:中序遍历二叉搜索树得到的是一个递增的序列,累加树每个节点的新值也就是序列中该节点及其后面的序列求和。所以我们反中序(右中左)遍历的同时记录累加和即可。

通过代码:

class Solution {
public:
    int sum = 0;
    void traverse(TreeNode *root){
        if(!root)
            return;
        traverse(root -> right);
        sum += root -> val;
        root -> val = sum;
        traverse(root -> left);
    }

    TreeNode* convertBST(TreeNode* root) {
        traverse(root);
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

h0l10w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值