多位95后程序员获公司700万大奖。。。

d48f2d3d1d35b4861dd50c8fc1bddc1a.gif

精品推荐

《征服数据结构》专栏:50多种数据结构彻底征服

《经典图论算法》专栏:50多种经典图论算法全部掌握

在百度9月19日内部活动上,李彦宏为激励员工的创新与研发精神,给4支内部团队颁发“百度最高奖”,每支团队获奖100万美元(合700万人民币),总额超2800万人民币,获奖团队中有多位95后成员。

在活动上,李彦宏说:“不是说,公司比较顺的时候,我们多发几个奖,逆境的时候,我们就少发几个奖,我们再苦不能苦技术人员,百度的技术信仰是一贯的 ,是永远的。”

94a73b2e1cdf70c60d57b6a746be2bbf.png

--------------下面是今天的算法题--------------

来看下今天的算法题,这题是LeetCode的第99题:恢复二叉搜索树。

问题描述

来源:LeetCode第99题

难度:中等

给你二叉搜索树的根节点 root ,该树中的恰好两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。

示例1:

0ee9c5ca06164ab675d17447fc7378ae.jpeg

输入:root = [1,3,null,null,2]

输出:[3,1,null,null,2]

解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。

示例2:

8f5cc1b163e3d9911b9fe602e802b5bd.jpeg

输入:root = [3,1,4,null,null,2]

输出:[2,1,4,null,null,3]

解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。

  • 树上节点的数目在范围 [2, 1000] 内

  • -2^31 <= Node.val <= 2^31 - 1

问题分析

这题说的是一颗二叉搜索树的两个节点被错误的交换,让我们恢复这棵二叉搜索树。

我们知道二叉搜索树的中序遍历结果是有序的,我们只需要对这棵二叉搜索树进行中序遍历,就可以找出这两个错误的节点,最后交换它们的值即可。

比如正常二叉搜索树中遍历的结果是:[1,2,3,4,5],是有序的,由于错误交换两个节点,比如2和4交换,导致中序遍历的结果变成[1,4,3,2,5],在中序遍历的时候每次都会和前一个节点值比较,如果当前节点比前一个节点值小,说明出现了错误的节点。

比如第一次3比4小,说明4(pre)是第一个错误节点,第二次是2比3小,说明2(cur)是第二个错误节点,最后交换它们的值即可。

JAVA:

private TreeNode pre;// 前一个节点
private TreeNode first;// 第一个错误节点
private TreeNode second;// 第二个错误节点

public void recoverTree(TreeNode root) {
    inorder(root);// 二叉树的中序遍历
    // 交换两个节点
    int tmp = first.val;
    first.val = second.val;
    second.val = tmp;
}

private void inorder(TreeNode cur) {
    if (cur == null)
        return;
    inorder(cur.left);// 递归左子树

    // 先找第一个错误节点,如果当前节点比前一个节点值小,说明前一个节点是错误的。
    if (first == null && pre != null && cur.val < pre.val)
        first = pre;
    // 第一个错误节点找到之后再找第二个。
    if (first != null && cur.val < pre.val)
        second = cur;

    pre = cur;// 更新前一个节点
    inorder(cur.right);// 递归右子树
}

C++:

private:
    TreeNode *pre;// 前一个节点
    TreeNode *first;// 第一个错误节点
    TreeNode *second;// 第二个错误节点

    void inorder(TreeNode *cur) {
        if (cur == nullptr)
            return;
        inorder(cur->left);// 递归左子树

        // 先找第一个错误节点,如果当前节点比前一个节点值小,说明前一个节点是错误的。
        if (first == nullptr && pre && cur->val < pre->val)
            first = pre;
        // 第一个错误节点找到之后再找第二个。
        if (first && cur->val < pre->val)
            second = cur;

        pre = cur;// 更新前一个节点
        inorder(cur->right);// 递归右子树
    }

public:
    void recoverTree(TreeNode *root) {
        inorder(root);// 二叉树的中序遍历
        // 交换两个节点的值
        int tmp = first->val;
        first->val = second->val;
        second->val = tmp;
    }

Python:

def recoverTree(self, root: Optional[TreeNode]) -> None:
    self.pre = None  # 前一个节点
    self.first = None  # 第一个错误节点
    self.second = None  # 第二个错误节点

    def inorder(cur):
        if cur is None:
            return
        inorder(cur.left)  # 递归左子树

        # 先找第一个错误节点,如果当前节点比前一个节点值小,说明前一个节点是错误的。
        if self.first is None and self.pre is not None and cur.val < self.pre.val:
            self.first = self.pre
            # 第一个错误节点找到之后再找第二个。
        if self.first is not None and cur.val < self.pre.val:
            self.second = cur

        self.pre = cur  # 更新前一个节点
        inorder(cur.right)  # 递归右子树

    inorder(root)  # 二叉树的中序遍历
    # 交换两个节点
    self.first.val, self.second.val = self.second.val, self.first.val

4de9d1b90b2be040b85d20a758f81ff7.gif

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

《征服数据结构》专栏

数组稀疏表(Sparse Table)单向链表双向链表块状链表跳表队列和循环队列双端队列单调队列单调栈双端栈散列表字典树(Trie树)ArrayMapSparseArray二叉树二叉搜索树(BST)笛卡尔树AVL树树堆(Treap)FHQ-Treap

……

《经典图论算法》专栏

图的介绍图的表示方式邻接矩阵转换广度优先搜索(BFS)深度优先搜索(DFS)A*搜索算法迭代深化深度优先搜索(IDDFS)IDA*算法双向广度优先搜索迪杰斯特拉算法(Dijkstra)贝尔曼-福特算法(Bellman-Ford)SPFA算法弗洛伊德算法(Floyd)

……

猜你喜欢

转载自blog.csdn.net/abcdef314159/article/details/142503915