一半员工净资产过亿,英伟达中国员工自爆工资单

4,941 阅读6分钟

英伟达

据风险投资人 Ruben D 透露:芯片巨头英伟达 78% 的员工已成为百万美元富翁,有一半人的净资产甚至达到 2500 万美元(约合人民币 1.83 亿元)。

英伟达的薪资很高,但光靠现金薪资不足让一半人资产过亿,这里面的主要原因,是英伟达 🚀 一般的涨幅,在过去五年翻了 20 倍。

英伟达作为"卖铲子"的人,总能精准踩中每个风口。

工业设计软件、3A游戏、虚拟货币、AI,带来了海量订单的同时,也把"濒死"的英伟达一度拉到「全球市值第一」的位置。

要知道,如今让全球科技公司都"高攀不起"的英伟达 CEO 黄仁勋,十年前还只能蹭刚起步的小米发布会来推销芯片。

当年,雷军还不是现在的"雷神",小米手机也才出到第三代。但即使是这般初创品牌的客户,也足以让黄仁勋毕恭毕敬。

十年河东十年河西,如今英伟达的市值,接近 50 个小米,不少有着股权激励的员工,身家也得以水涨船高。

这几年行情不景气,网上晒工资的人少了许多(或被限流),但仍然找到了一份 2021 年英伟达员工收入的资料:

该员工在 2021 年底共有 3 笔收入:股权激励 900W+、全年一次性奖金 16W+,月工资 17W+。

知道英伟达员工收入高,但却是我想象不到的高 🤣🤣🤣

而且,这还是 2021 年的英伟达,当时一股英伟达 30 不到,如今 130+(涨幅 433%),这两年的股权激励会去到多少,我不敢想 🤣🤣🤣

但巨额财富背后是高强度的工作,据英伟达员工爆料,他们基本每周工作 7 天,加班到凌晨 2 点也是常态,还要面临密集的会议安排和严格的时间管理要求,大家几乎没有多少时间陪伴家人,甚至开始考虑"半退休"状态,以缓解工作带来的负面影响。

对此,你怎么看?说实话,你是不是也想体验几年加班到 2 点的日子?欢迎评论区交流。

...

回归主题。

来一道「HOT 100」级别算法题。

题目描述

平台:LeetCode

题号:450

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

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

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

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3

输出:[5,4,6,2,null,null,7]

解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。

另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0

输出: [5,3,6,2,4,null,7]

解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0

输出: []

提示:

  • 节点数的范围 [0,104][0, 10^4]
  • 105 <=Node.val<=105-10^5 <= Node.val <= 10^5
  • 节点值唯一
  • root 是合法的二叉搜索树
  • 105 <=key<=105-10^5 <= key <= 10^5

进阶: 要求算法时间复杂度为 O(h)O(h)hh 为树的高度。

递归

利用题目本身的函数签名的含义,也就是「在以 root 为根的子树中,删除值为 key 的节点,并返回删除节点后的树的根节点」,我们可以用「递归」来做。

起始先对边界情况进行处理,当 root 为空(可能起始传入的 root 为空,也可能是递归过程中没有找到值为 key 的节点时,导致的 root 为空),我们无须进行任何删除,直接返回 null 即可。

根据当前 root.valkey 的大小关系,进行分情况讨论:

  1. 若有 root.val<keyroot.val < key,说明待删除的节点必然不是当前节点,以及不在当前节点的左子树中,我们将删除动作「递归」到当前节点的右子树,并将删除(可能进行)之后的新的右子树根节点,重新赋值给 root.right,即有 root.right = deleteNode(root.right, key)

  2. 若有 root.val>keyroot.val > key,说明待删除的节点必然不是当前节点,以及不在当前节点的右子树,我们将删除节点「递归」到当前节点的左子树,并将删除(可能进行)之后的新的左子树根节点,重新赋值给 root.left,即有 root.left = deleteNode(root.left, key)

  3. 若有 root.val=keyroot.val = key,此时找到了待删除的节点,我们根据左右子树的情况,进行进一步分情况讨论:

    • 若左/右子树为空,我们直接返回右/左子树节点即可(含义为直接将右/左子树节点搬到当前节点的位置)如图所示:

    • 若左右子树均不为空,我们有两种选择:

      • 从「当前节点的左子树」中选择「值最大」的节点替代 root 的位置,确保替代后仍满足 BST 特性;
      • 从「当前节点的右子树」中选择「值最小」的节点替代 root 的位置,确保替代后仍满足 BST 特性;

      我们以「从当前节点的左子树中选择值最大的节点」为例子,我们通过树的遍历,找到其位于「最右边」的节点,记为 tttt 作为最右节点,必然有 t.right = null),利用原本的 root 也是合法 BST,原本的 root.right 子树的所有及节点,必然满足大于 t.val,我们可以直接将 root.right 接在 t.right 上,并返回我们重接后的根节点,也就是 root.left

      而「从当前节点的右子树中选择值最小的节点」,同理(代码见 P2P2)。

Java 代码(P1):

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val == key) {
            if (root.left == null) return root.right;
            if (root.right == null) return root.left;
            TreeNode t = root.left;
            while (t.right != null) t = t.right;
            t.right = root.right;
            return root.left;
        } else if (root.val < key) root.right = deleteNode(root.right, key);
        else root.left = deleteNode(root.left, key);
        return root;
    }
}

Java 代码(P2):

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val == key) {
            if (root.left == null) return root.right;
            if (root.right == null) return root.left;
            TreeNode t = root.right;
            while (t.left != null) t = t.left;
            t.left = root.left;
            return root.right;
        } else if (root.val < key) root.right = deleteNode(root.right, key);
        else root.left = deleteNode(root.left, key);
        return root;
    }
}

C++ 代码(P1):

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

Python 代码(P1):

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return None
        if root.val == key:
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            t = root.left
            while t.right:
                t = t.right
            t.right = root.right
            return root.left
        elif root.val < key:
            root.right = self.deleteNode(root.right, key)
        else:
            root.left = self.deleteNode(root.left, key)
        return root

TypeScript 代码(P1):

function deleteNode(root: TreeNode | null, key: number): TreeNode | null {
    if (!root) return null;
    if (root.val === key) {
        if (!root.left) return root.right;
        if (!root.right) return root.left;
        let t: TreeNode | null = root.left;
        while (t!.right) t = t!.right;
        t!.right = root.right;
        return root.left;
    } else if (root.val < key) {
        root.right = deleteNode(root.right, key);
    } else {
        root.left = deleteNode(root.left, key);
    }
    return root;
};
  • 时间复杂度:O(h)O(h),其中 hh 为树的深度
  • 空间复杂度:忽略递归带来的额外空间消耗,复杂度为 O(1)O(1)