不是所有字节人都在意倒挂的(含字节面试算法原题)

组织内的击鼓传花

上周,我们讲了 字节跳动的校招薪资

结合其他大厂的校招薪资来看,基本上可以得出一个结论:互联网这几年虽然不行,但是倒挂一下几年前的老人,还是没什么问题的。

但另一个问题油然而生:我们也会成为老人,我们到时候也只能被动接受「裁员」或「倒挂」的现实吗?

裁员问题,一个企业内的成规模裁员,和自身的努力程度,关系不大,跟所在组织和产品线发展路线,关系较大。

我们无法预计所在组织或产品线的未来。

因此裁员问题,作为个体,除非我们发挥主观能动性,持续地投身到热门行业,否则无解。

现实里,大多数人还是期望在一个较好的环境中待久一点的。

因此,与其考虑无解的裁员问题,不如想想如何"解决"倒挂。

要找到这个问题的答案,我们可以从现在的环境中,找那些并没有因为"倒挂"产生落差的老员工。

看他们是从哪些地方填满了倒挂空缺。

能抵御新人薪资倒挂带来的心理落差,说明他们在其他地方获得了财富增值的先发优势。

通常是「外部优势」或「内部优势」:

  • 外部优势:这部分的老员工,通常是搭上了二趟的时代红利,从而放大了先发优势;

    第一趟是入职互联网行业,第二趟一般是坐上了房地产的尾班车。

  • 内部优势:这部分的老员工,通常是凭借早入职,拿到了大量股票期权;

    要么已经上市,套现获利了,要么尚未上市,但公司有持续的内部回购,也是一种持续升值。

听起来,老员工的三条路「房地产」、「上市造富」和「股票内购」,只有最后者还有复刻的可能性。

这又要说回我们的老朋友「字节跳动」。

虽然字节跳动尚未上市,但其内部一年两次的回购,基本上每次都上热搜。

可能会有同学有疑问:字节没上市,也能造富?

我给的结论,可能有点难理解:恰好是因为没上市,才能以满足预期的进度来持续造富。

我先简单介绍一下玩法吧。

字节的期权,可大概分为两大类,"奖金类"和"非奖金类"。

入职的时候,通常给的期权是非奖金类的,一般分四年归属(可以理解为实际到账),归属后能卖一半,剩下一半要 5 年后才能卖完。

奖金类的期权,通常是在发放年终奖的时候产生的,例如某年年终奖是 20W,可以选当中的多少拿现金,多少拿期权,这部分的期权是归属满一年后能卖一半,剩下的需要下一年才能卖完。

哎,这里可能会有人会问:那离职或者被辞退,是不是变废纸了?不是,如果是归属了,还能以 8 折参与内部回购。

了解完基本规则,再看看近几年字节每股回购价格变化(单位:美元):

  • 18年:10+
  • 19年:30+
  • 20年:60-70
  • 21年:126
  • 22年4月:140
  • 22年10月:155
  • 23年4月:155
  • 23年10月:160

可能看着这价格变化,内心还是没有波澜,来看一个 🍋 例子:

按照最新的回购价 160美元/股,8.4k 股大概价值税前 950W 人民币。

18 年入职,因此入职送的期权都已归属完。

同时能攒到 8k 股,估计大多都是在 2020 年之前攒的。

如果是在 19 年攒的,现在已经可以一把全卖了,如果是 20 年攒的,那也是明年的事情。

你说对于这样的字节老员工,倒不倒挂的,区别大吗?

这一类的老员工目前需要考虑的,是如何弄一个 HK 身份,来降低参与回购需要缴纳的税收。

毕竟前后相差:950 * (0.45 - 0.17) = 266W(大陆 45%,HK 17%)。

扯远了,看到这里,还是需要叫停一下大家的 🍋 思绪。

...

回归到刚开始说的如何"解决"倒挂。

房子是不可能买房子的了,中概互联也跌落神坛,以前没卖的小伙伴,现在都是腰砍再腰砍。

那剩下的最后一条道路:积极参与到公司「股票内购」,能否作为"解决"倒挂的答案?

这需要看背后有何风险。

细想便知,最大的风险,不是被辞退(期权都已归属),也不是企业倒闭(可能性极低)。

真正的风险是:企业真的上市,如今的节骨眼下上市,上市可能价格会一下子跌回 30+。

随着这几年互联网在金融市场的不受待见,以蚂蚁金服的 IPO 被叫停为分界线,将来可能会有越来越多的公司搞这种"击鼓传花"的内部游戏。

上市凶多吉少,不上市确实能造福,但能否参与需要从两个维度分析:

  1. 公司是否真的在高速发展道路上(值博率,是否值得参与),且会在较短时间内大到一定规模(是否会有变废纸风险);

  2. 了解一下公司的盈利组成,从现实的角度去分析,公司是否有足够的利润支撑下去。

    这里说的支撑,不仅仅是支撑公司正常运营,还有公司创始人/高管的耐心;你用年终奖现金,以内购价买股,公司上市,价格下跌,只是你的对赌失败;但对创始人来说,怎么跌,也是数千亿的财富增值

...

回到主线,想拿期权得先进去,进字节不会算法题可不行。

前几天做了「特定值的四元组问题」,今天来做到一道简单的「三元组」问题。

题目描述

平台:LeetCode

题号:15

给你一个包含 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 个整数的数组 nums

判断 nums 中是否存在三个元素 abc ,使得 a + b + c = 0

请你找出所有和为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 0 </math>0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

lua 复制代码
输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

示例 2:

ini 复制代码
输入:nums = []

输出:[]

示例 3:

ini 复制代码
输入:nums = [0]

输出:[]

提示:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 < = n u m s . l e n g t h < = 3000 0 <= nums.length <= 3000 </math>0<=nums.length<=3000
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> − 1 0 5 < = n u m s [ i ] < = 1 0 5 -10^5 <= nums[i] <= 10^5 </math>−105<=nums[i]<=105

排序 + 双指针

对数组进行排序,使用三个指针 ijk 分别代表要找的三个数。

  1. 通过枚举 i 确定第一个数,另外两个指针 jk 分别从左边 i + 1 和右边 n - 1 往中间移动,找到满足 nums[i] + nums[j] + nums[k] == 0 的所有组合。

  2. jk 指针的移动逻辑,分情况讨论 sum = nums[i] + nums[j] + nums[k]

    • sum > 0:k 左移,使 sum 变小
    • sum < 0:j 右移,使 sum 变大
    • sum = 0:找到符合要求的答案,存起来

由于题目要求答案不能包含重复的三元组,所以在确定第一个数和第二个数的时候,要跳过数值一样的下标(在三数之和确定的情况下,确保第一个数和第二个数不会重复,即可保证三元组不重复)。

Java 代码:

Java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int j = i + 1, k = n - 1;
            while (j < k) {
                while (j > i + 1 && j < n && nums[j] == nums[j - 1]) j++;
                if (j >= k) break;
                int sum = nums[i] + nums[j] + nums[k];
                if (sum == 0) {
                    ans.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    j++;
                } else if (sum > 0) {
                    k--;
                } else if (sum < 0) {
                    j++;
                }
            }
        }
        return ans;
    }
}

C++ 代码:

C++ 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        vector<vector<int>> ans;
        for (int i = 0; i < n; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int j = i + 1, k = n - 1;
            while (j < k) {
                while (j > i + 1 && j < n && nums[j] == nums[j - 1]) j++;
                if (j >= k) break;
                int sum = nums[i] + nums[j] + nums[k];
                if (sum == 0) {
                    ans.push_back({nums[i], nums[j], nums[k]});
                    j++;
                } else if (sum > 0) {
                    k--;
                } else if (sum < 0) {
                    j++;
                }
            }
        }
        return ans;   
    }
};

Python 代码:

Python 复制代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        ans = []
        for i in range(n):
            if i > 0 and nums[i] == nums[i - 1]: continue
            j, k = i + 1, n - 1
            while j < k:
                while j > i + 1 and j < n and nums[j] == nums[j - 1]:
                    j += 1
                if j >= k: break
                _sum = nums[i] + nums[j] + nums[k]
                if _sum == 0:
                    ans.append([nums[i], nums[j], nums[k]])
                    j += 1
                elif _sum > 0:
                    k -= 1
                elif _sum < 0:
                    j += 1
        return ans

TypeScript 代码:

TypeScript 复制代码
function threeSum(nums: number[]): number[][] {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    const ans = [];
    for (let i = 0; i < n; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) continue;
        let j = i + 1, k = n - 1;
        while (j < k) {
            while (j > i + 1 && j < n && nums[j] === nums[j - 1]) j++;
            if (j >= k) break;
            const sum = nums[i] + nums[j] + nums[k];
            if (sum === 0) {
                ans.push([nums[i], nums[j], nums[k]]);
                j++;
            } else if (sum > 0) {
                k--;
            } else if (sum < 0) {
                j++;
            }
        }
    }
    return ans;
};
  • 时间复杂度:排序的复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n log ⁡ n ) O(n\log{n}) </math>O(nlogn),对于每个 i 而言,最坏的情况 jk 都要扫描一遍数组的剩余部分,复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2)。整体复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2)
  • 空间复杂度: <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( log ⁡ n ) O(\log{n}) </math>O(logn)

我是宫水三叶,每天都会分享算法题解,并和大家聊聊近期的所见所闻。

欢迎关注,明天见。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

相关推荐
攸攸太上13 分钟前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
罗曼蒂克在消亡30 分钟前
graphql--快速了解graphql特点
后端·graphql
潘多编程32 分钟前
Spring Boot与GraphQL:现代化API设计
spring boot·后端·graphql
大神薯条老师1 小时前
Python从入门到高手4.3节-掌握跳转控制语句
后端·爬虫·python·深度学习·机器学习·数据分析
前端李易安2 小时前
Web常见的攻击方式及防御方法
前端
2401_857622662 小时前
Spring Boot新闻推荐系统:性能优化策略
java·spring boot·后端
PythonFun2 小时前
Python技巧:如何避免数据输入类型错误
前端·python
Neituijunsir2 小时前
2024.09.22 校招 实习 内推 面经
大数据·人工智能·算法·面试·自动驾驶·汽车·求职招聘
hakesashou2 小时前
python交互式命令时如何清除
java·前端·python
天涯学馆2 小时前
Next.js与NextAuth:身份验证实践
前端·javascript·next.js