字节的晋升机制,到底逼走了多少人。

最近在网上看到一个帖子,一网友说字节有个非常无耻的晋升机制,就是在一定年限内,如果你升不上高title,哪怕你表现的和以前一样好,一样被开掉,因为你已经停止进步了。

f1c9b0ded5e08b30c946590dbd721d86.png

对于字节的这种晋升机制,很多网友说只不过是公司开除员工的一个借口而已。还有网友说晋升都是靠关系,谁有关系谁晋升。还有“停止进步”这种话太过主观,无法量化;只是以果推因,给开除你找个理由罢了。

48a9e16b1453302def90e6bec8d2be7f.png

6b592c6a5a51a60bdb038e661cfd6cf7.png

eefb8ac8e252cc30ba81c90c25d543b5.png

e00a475fa7ad61bd801a9e39a90a0f56.png

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

看完了字节的晋升机制,我们再来看一道字节的面试题,这题是LeetCode的第40题:组合总和 II。这题字节,小米,华为等大厂都考过,我们来看下。

59fea89626955abd81b4a005c86c8cd6.png

问题描述

来源:LeetCode第40题

难度:中等

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

示例1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,

输出:

[

[1,1,6],

[1,2,5],

[1,7],

[2,6]

]

示例2:

输入: candidates = [2,5,2,1,2], target = 5,

输出:

[

[1,2,2],

[5]

]

  • 1 <= candidates.length <= 100

  • 1 <= candidates[i] <= 50

  • 1 <= target <= 30

回溯算法解决

这题是让从数组中找出一些数字,让他们的和等于target,然后列出所有和等于target的组合,在前面我们讲过《组合总和》,不过前面一道题数组中没有重复的元素,这题是有重复的元素,如果还按照前面那题的解法,会出现重复的结果。

这题和我们前面讲的那题解法非常类似,只需要过滤掉重复的结果即可,怎么过滤呢,我们画个图看下:

7d6378b6b08ad61db73c21b8c301300e.png

实际上可以把它看作是一棵树,因为每个数字最多只能选择一次,所以选择完当前数字之后下一步要从他的下一个数字开始。上面图中因为有相同的数字,所以结果出现了重复。只需要把重复的剪掉即可。

在计算之前我们需要先对数组排序,这样重复的数字就会挨着了,当出现重复数字的时候,前面数字构成的子集实际上是包含后面数字构成的所有子集,所以当出现重复数字的时候我们需要把后面数字构成的分支剪掉即可。

JAVA:

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
    List<List<Integer>> ans = new ArrayList<>();
    Arrays.sort(candidates);// 先排序
    backTrack(ans, new ArrayList<>(), candidates, target, 0);
    return ans;
}

private void backTrack(List<List<Integer>> ans, List<Integer> path,
                       int[] candidates, int target, int start) {
    if (target == 0) {
        ans.add(new ArrayList<>(path));
        return;
    }
    for (int i = start; i < candidates.length; i++) {
        // 因为是有序的,后面的值越来越大,直接终止。
        if (target < candidates[i])
            break;
        if (i > start && candidates[i] == candidates[i - 1])
            continue; // 去掉重复的
        path.add(candidates[i]);// 选择
        backTrack(ans, path, candidates, target - candidates[i], i + 1);
        path.remove(path.size() - 1);// 撤销选择
    }
}

C++:

public:
    vector<vector<int>> combinationSum2(vector<int> &candidates, int target) {
        vector<vector<int>> ans;
        sort(candidates.begin(), candidates.end());// 先排序
        vector<int> path;
        backTrack(ans, path, candidates, target, 0);
        return ans;
    }

    void backTrack(vector<vector<int>> &ans, vector<int> &path,
                   vector<int> &candidates, int target, int start) {
        if (target == 0) {
            ans.emplace_back(path);
            return;
        }
        for (int i = start; i < candidates.size(); i++) {
            // 因为是有序的,后面的值越来越大,直接终止。
            if (target < candidates[i])
                break;
            if (i > start && candidates[i] == candidates[i - 1])
                continue; // 去掉重复的
            path.emplace_back(candidates[i]);// 选择
            backTrack(ans, path, candidates, target - candidates[i], i + 1);
            path.pop_back();// 撤销选择
        }
    }

C:

int cmp(const void *a, const void *b) {
    return *(const int *) a - *(const int *) b;
}

void backTrack(int **ans, int *path, int *candidates, int candidatesSize, int target,
               int start, int *returnSize, int **returnColumnSizes, int pathCount) {
    if (target == 0) {
        ans[*returnSize] = (int *) malloc(pathCount * sizeof(int));
        memcpy(ans[*returnSize], path, pathCount * sizeof(int));
        (*returnColumnSizes)[*returnSize] = pathCount;
        (*returnSize)++;
        return;
    }
    for (int i = start; i < candidatesSize; i++) {
        // 因为是有序的,后面的值越来越大,直接终止。
        if (target < candidates[i])
            break;
        if (i > start && candidates[i] == candidates[i - 1])
            continue; // 去掉重复的
        path[pathCount++] = candidates[i];// 选择
        backTrack(ans, path, candidates, candidatesSize, target - candidates[i],
                  i + 1, returnSize, returnColumnSizes, pathCount);
        --pathCount;// 撤销选择
    }
}

int **combinationSum2(int *candidates, int candidatesSize, int target,
                      int *returnSize, int **returnColumnSizes) {
    // 先进行排序
    qsort(candidates, candidatesSize, sizeof(int), cmp);
    int n = 3000;
    int **ans = (int **) malloc(sizeof(int *) * n);
    *returnColumnSizes = (int *) malloc(sizeof(int) * n);
    int *path = (int *) malloc(sizeof(int) * n);
    *returnSize = 0;
    backTrack(ans, path, candidates, candidatesSize, target, 0, returnSize, returnColumnSizes, 0);
    return ans;
}

Python:

def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
    def backtrack(res: list[list[int]], path: list[int], candidates: list[int], target: int, start: int):
        if target == 0:
            res.append(list(path))
            return
        for i in range(start, len(candidates)):
            # 因为是有序的,后面的值越来越大,直接终止。
            if target < candidates[i]:
                break
            if i > start and candidates[i] == candidates[i - 1]:
                continue  # 去掉重复的
            path.append(candidates[i])  # 选择
            backtrack(res, path, candidates, target - candidates[i], i + 1)
            path.pop()  # 撤销选择

    candidates.sort()  # 先对数组进行排序
    ans = []  # 需要返回的结果
    path = []
    backtrack(ans, path, candidates, target, 0)
    return ans

40f1697a314b7765438f0f13e8847cfa.gif

笔者简介

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

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

数据结构和算法

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

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

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

打赏作者

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

抵扣说明:

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

余额充值