神仙公司名单(广州)

579 阅读7分钟

神仙公司(广州)

续集来咯,上次 厦门神仙公司 中留言最多的城市,是广州,速速安排。

由于神仙公司不多,HC 通常也有限,因此,除了分享一些毫无争议的神仙公司以外,还会把一些相对较好的"半仙"公司也分享给大家。

一直很稳的 WLB 典范(神仙公司):

  • P&G 宝洁:弹性工作制,18 天带薪年假,定期绩效调薪,团队奖金,个人奖金,各类补贴和员工福利,14 薪起;
  • 爱迪生:六险一金,公积金双边 12%,额外补充的商业保险覆盖配偶和子女,通勤时间早上9点到晚上5点半(午休 2 小时),不打卡不加班;
  • 汇量科技:氛围偏外企,定期调薪,团队奖金,个人奖金,关键员工持股计划,包三餐和下午茶,15~16 薪;
  • 唯品会:三餐包吃(还有零食下午茶),包车接送,甚至包住(员工公寓 300/月,住宿标准对标 3000/元),节日福利,补充医疗保险,股票期权,13~15 薪;
  • 广发证券:5点下班,不加班,提供餐补,交通补贴,员工旅游,节日福利,补充医疗保险,13~15 薪;

还算不错的企业(半仙公司):

  • 西门子:不打卡,工资水平一般,胜在稳定不卷,福利尚可,加班补助,交通补助,节日福利,年终奖;
  • 大参林:免费班车,免费住宿,员工旅游,节日福利,提供餐补,偶尔加班,年终奖;
  • 塔塔:免费班车,补充医疗体检,加班补助,项目奖金,个人奖金,绩效奖金,定期普调,节日福利,13 薪;
  • 汇丰银行:弹性工作制,可居家办公,10~25 天带薪年假,带薪病假,补充商业医疗险,正式员工 HC 近期收紧;
  • 天翼云:央企,交通补,餐补,通讯补,节日福利,补充医疗保险,有 3~6 个月试用期,部分组别互联网气息较重,15 薪;

以上都是坐标广州,有计算机相关在招岗位的企业。其中「汇量科技/唯品会/塔塔」是标准互联网软件行业,「唯品会/广发证券/天翼云」目前 HC 最多。

广州是几个大一线城市里最有人情味的。

关于「广州」以及「广州的神仙公司」,你有什么想分享的呢,欢迎评论区留言。

...

回归主线。

来一道广东人都很喜欢的(888)算法题。

题目描述

平台:LeetCode

题号:888

爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 根糖果棒的大小,B[j] 是鲍勃拥有的第 j 根糖果棒的大小。

因为他们是朋友,所以他们想交换一根糖果棒,这样交换后,他们都有相同的糖果总量(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和)。

返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是鲍勃必须交换的糖果棒的大小。

如果有多个答案,你可以返回其中任何一个。

保证答案存在。

示例 1:

输入:A = [1,1], B = [2,2]

输出:[1,2]

示例 2:

输入:A = [1,2], B = [2,3]

输出:[1,2]

示例 3:

输入:A = [2], B = [1,3]

输出:[2,3]

示例 4:

输入:A = [1,2,5], B = [2,4]

输出:[5,4]

提示:

  • 1<=A.length<=100001 <= A.length <= 10000
  • 1<=B.length<=100001 <= B.length <= 10000
  • 1<=A[i]<=1000001 <= A[i] <= 100000
  • 1<=B[i]<=1000001 <= B[i] <= 100000
  • 保证爱丽丝与鲍勃的糖果总量不同
  • 答案肯定存在

朴素解法

最终目的是让两个数组总和相等。

我们可以先分别求得两个数组总和为 aSumbSum

即有数组总和 total = aSum + bSum

同时得数组目标总和 target = total / 2

当前两个数组与目标总和的差值分别为 target - aSumtarget - bSum

我们记 diff = target - aSum

对于某个 a[i] 而言,如果 a[i] 能构成答案,那么 b 数组中必然存在大小为 a[i] + diff 的值,使得两者交换后,数组总和均为 target

因此我们只需要遍历数组 a,查找哪一个 a[i] 使得 a[i] + diff 存在于数组 b 即可。

Java 代码:

class Solution {
    public int[] fairCandySwap(int[] a, int[] b) {
        int aSum = 0, bSum = 0;
        for (int i : a) aSum += i;  
        for (int i : b) bSum += i;  
        int total = aSum + bSum, target = total / 2;
        int diff = target - aSum;
        for (int i : a) {
            if (find(b, i + diff)) return new int[]{i, i + diff};
        }
        return null; // never
    }
    boolean find(int[] nums, int target) {
        for (int i : nums) {
            if (i == target) return true;
        }
        return false;
    }
}

C++ 代码:

class Solution {
public:
    vector<int> fairCandySwap(vector<int>& a, vector<int>& b) {
        int aSum = 0, bSum = 0;
        for (int i : a) aSum += i;
        for (int i : b) bSum += i;
        int total = aSum + bSum, target = total / 2;
        int diff = target - aSum;
        vector<int> ans(2);
        for (int i : a) {
            if (find(b, i + diff)) {
                ans[0] = i; 
                ans[1] = i + diff;
                break;
            }
        }
        return ans;
    }
    bool find(vector<int>& nums, int target) {
        for (int i : nums) {
            if (i == target) return true;
        }
        return false;
    }
};

Python 代码:

class Solution:
    def fairCandySwap(self, a: List[int], b: List[int]) -> List[int]:
        aSum, bSum = sum(a), sum(b)
        total = aSum + bSum
        target = total // 2
        diff = target - aSum
        for i in a:
            if i + diff in b:
                return [i, i + diff]
        return None

TypeScript 代码:

function fairCandySwap(a: number[], b: number[]): number[] {
    let aSum = a.reduce((acc, val) => acc + val, 0);
    let bSum = b.reduce((acc, val) => acc + val, 0);
    let total = aSum + bSum;
    let target = Math.floor(total / 2);
    let diff = target - aSum;
    let ans: number[] = [];
    for (let i of a) {
        if (b.includes(i + diff)) {
            ans = [i, i + diff];
            break;
        }
    }
    return ans;
};
  • 时间复杂度: 计算总和复杂度为 O(n)O(n),找到最终解复杂度为 O(n2)O(n^2)。整体复杂度为 O(n2)O(n^2)
  • 空间复杂度:O(1)O(1)

查找优化

上述解法之所以无法做到线性,是因为我们每次都要对数组 b 进行扫描,确定 a[i] + diff 是否存在。

我们知道 map/set/数组 都可以实现 O(1)O(1) 查找,由于这里明确给出了两个数组中出现的数的范围,因此可以使用数组进行计数。

同时可以优化一下变量的使用,使用一个变量 diff 来计算最终的差异值。

这种优化,是典型的空间换时间做法。

Java 代码:

class Solution {
    public int[] fairCandySwap(int[] a, int[] b) {
        // 先求得 a 的总和
        int diff = 0;
        for (int i : a) diff += i;  
        // 使用 cnt 统计 b 中的数的出现次数,同时计算 a 总和与 b 总和的差值
        int[] cnt = new int[100009];
        for (int i : b) {
            diff -= i;
            cnt[i]++;
        }
        // 计算出 a 中具体的替换差值是多少
        diff /= -2;
        int[] ans = new int[2];
        for (int i : a) {
            int target = i + diff;
            // 如果目标替换量在合法范围,并且存在于 b 数组中。说明找到解了
            if (target >= 1 && target <= 100000 && cnt[target] > 0) {
                ans[0] = i;
                ans[1] = target;
                break;
            }
        }
        return ans;
    }
}

C++ 代码:

class Solution {
public:
    vector<int> fairCandySwap(vector<int>& a, vector<int>& b) {
        // 先求得 a 的总和
        int diff = 0;
        for (int i : a) diff += i;
        // 使用 cnt 统计 b 中的数的出现次数,同时计算 a 总和与 b 总和的差值
        vector<int> cnt(100009, 0);
        for (int i : b) {
            diff -= i;
            cnt[i]++;
        }
        // 计算出 a 中具体的替换差值是多少
        diff /= -2;
        vector<int> ans(2);
        for (int i : a) {
            int target = i + diff;
            // 如果目标替换量在合法范围,并且存在于 b 数组中。说明找到解了
            if (target >= 1 && target <= 100000 && cnt[target] > 0) {
                ans[0] = i;
                ans[1] = target;
                break;
            }
        }
        return ans;
    }
};

Python 代码:

class Solution:
    def fairCandySwap(self, a: List[int], b: List[int]) -> List[int]:
        # 先求得 a 的总和
        diff = sum(a)
        # 使用 cnt 统计 b 中的数的出现次数,同时计算 a 总和与 b 总和的差值
        cnt = [0] * 100009
        for i in b:
            diff -= i
            cnt[i] += 1
        # 计算出 a 中具体的替换差值是多少
        diff //= -2
        for i in a:
            target = i + diff
            # 如果目标替换量在合法范围,并且存在于 b 数组中。说明找到解了
            if 1 <= target <= 100000 and cnt[target] > 0:
                return [i, target]

TypeScript 代码:

function fairCandySwap(a: number[], b: number[]): number[] {
    // 先求得 a 的总和
    let diff = a.reduce((acc, curr) => acc + curr, 0);
    // 使用 cnt 统计 b 中的数的出现次数,同时计算 a 总和与 b 总和的差值
    let cnt: number[] = new Array(100009).fill(0);
    for (let i of b) {
        diff -= i;
        cnt[i]++;
    }
    // 计算出 a 中具体的替换差值是多少
    diff = Math.floor(diff / -2);
    for (let i of a) {
        let target = i + diff;
        // 如果目标替换量在合法范围,并且存在于 b 数组中。说明找到解了
        if (target >= 1 && target <= 100000 && cnt[target] > 0) {
            return [i, target];
        }
    }
    return [];
}
  • 时间复杂度:计算总和复杂度为 O(n)O(n),找到最终解复杂度为 O(n)O(n)。整体复杂度为 O(n)O(n)
  • 空间复杂度:使用 cnt 数组进行计数。复杂度为 O(n)O(n)