待遇最好的央国企名单

国企央企

写了好多期的神仙公司,每期都有评论说,这些公司相比于「国家电网」、「烟草局」,压根不能称为"神仙公司"。

但这些公司,不是说努力就能进的,不过多了解下总是好的。

今天就来给大家分享几家待遇福利领跑国企央企。

  • 中国烟草总公司:难怕只和央国企对比,中国烟草的待遇也是领先的。中国烟草的薪资构成包含基本工资、绩效工资、年终奖、节假日福利(发钱)各方面。应届生刚进去年收入收到大概是 20 万打底,然后每年还有不低于 10% 的普调。有些看惯了互联网年包收入的同学,可能觉得 20 万并不高,但你要知道,中国烟草还有诸多福利,全额的公积金,住房补贴,免费三餐等等,而且这 20 万是实打实的现金,互联网的年包虽然数字很大,但往往包含了需要多年才归属的股票期权,而且行业变数大,离职、裁员或者效益不好,都会导致尚未折现的收入大打折扣,而在中国烟草,这些都不存在。

  • 国家电网:电力行业的稳定性不是一般的高,但相比于其他央国企,国家电网会有周期性的工作强度(但也只是相比于其他央国企而言,对标正常企业,那都不叫工作量),而且薪酬福利十分优渥,本科生转正一般在到手 15 万左右,研究生的话到手 20 万左右。除了有上述中国烟草提到的福利待遇以外,国家电网还会根据员工所在地区,发放高温补贴、防寒防暑费、职工疗养等等。

  • 中国石油天然气股份有限公司(中石油):中石油作为国有重要骨干企业和全球主要的油气生产商和供应商之一,基本工资包括 岗位工作、技能工资、绩效奖金 和 年终奖。福利待遇包括五险一金(部分地区六险二金),还有地区补贴等等。虽然应届入职年薪到手只有 10 万,但晋升制度完善,基本上工龄上去之后,普遍都能到手 20 万,同时提供环境不错的公租房和员工公寓,如果在城市买房还会有一次性安家费发放,更重要的是在京员工还能解决落户问题。

  • 中国石油化工集团公司(中石化):如果中石油是铁饭碗,那中石化可以说是金饭碗。无论是技术岗还是管理岗,年薪几十万的大有人在。同时社保和公积金都是全额提交,另外还有住房补贴、节日福利、通话补贴、交通补贴以及员工退休金计划(企业帮员工存钱)。

  • 五大国有银行:五大国有行是指「工行、建行、中行、农行和交行」,这可能是相对好进的央国企了,其他央国企想走社招简直是地狱难度,但五大行,尤其是研发这一块,如果有相关的金融背景以及大厂履历,还是很有可能社招进去的,技术人员进去之后基本只做管理工作了,实际的开发任务大多都由外包完成。

以上就是了解到几家待遇不错的央国企,你还知道哪些神仙央国企?欢迎评论区交流。

...

回归主题。

来一道周末小算法。

题目描述

平台:LeetCode

题号:88

给你两个有序整数数组 nums1nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1nums2 的元素数量分别为 mn

你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

输出:[1,2,2,3,5,6]

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0

输出:[1]

提示:

模拟

最简单的做法,我们可以将 的内容先搬到 去,再对 进行排序。

Java 代码:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        System.arraycopy(nums2, 0, nums1, m, n);
        Arrays.sort(nums1);
    }
}

C++ 代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        copy(nums2.begin(), nums2.end(), nums1.begin() + m);
        sort(nums1.begin(), nums1.end());
    }
};

Python 代码:

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        nums1[m:m+n] = nums2
        nums1.sort()

TypeScript 代码:

function merge(nums1: number[], m: number, nums2: number[], n: number): void {
    nums1.splice(m, n, ...nums2);
    nums1.sort((a, b) => a - b);
};
  • 时间复杂度:
  • 空间复杂度:

「PS. Java 中的 sort 排序是一个综合排序。包含插入/双轴快排/归并/timsort,这里假定 Arrays.sort 使用的是「双轴快排」,并忽略递归带来的空间开销。」

双指针 - 额外空间

上述方法,粗暴地将两个数组结合,再对结果进行排序,没有很好利用俩数组本身有序的特性。

一个容易想到的,可以避免对结果排序的做法是:创建一个和 等长的数组 ,使用双指针将 的数据迁移到 ,最后再将 复制到 中。

Java 代码:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int total = m + n, idx = 0;
        int[] arr = new int[total];
        for (int i = 0, j = 0; i < m || j < n;) {
            if (i < m && j < n) {
                arr[idx++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
            } else if (i < m) {
                arr[idx++] = nums1[i++];
            } else if (j < n) {
                arr[idx++] = nums2[j++];
            }
        }
        System.arraycopy(arr, 0, nums1, 0, total);
    }
}

C++ 代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int total = m + n, idx = 0;
        vector<intarr(total);
        for (int i = 0, j = 0; i < m || j < n;) {
            if (i < m && j < n) {
                arr[idx++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
            } else if (i < m) {
                arr[idx++] = nums1[i++];
            } else if (j < n) {
                arr[idx++] = nums2[j++];
            }
        }
        copy(arr.begin(), arr.end(), nums1.begin());
    }
};

Python 代码:

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        total, idx = m + n, 0
        arr = [0] * total
        i, j = 00
        while i < m or j < n:
            if i < m and j < n:
                if nums1[i] < nums2[j]:
                    arr[idx] = nums1[i]
                    i += 1
                else:
                    arr[idx] = nums2[j]
                    j += 1
                idx += 1
            elif i < m:
                arr[idx] = nums1[i]
                idx += 1
                i += 1
            elif j < n:
                arr[idx] = nums2[j]
                idx += 1
                j += 1

        for i in range(total):
            nums1[i] = arr[i]

TypeScript 代码:

function merge(nums1: number[], m: number, nums2: number[], n: number): void {
    let total = m + n, idx = 0;
    const arr = new Array(total);
    for (let i = 0, j = 0; i < m || j < n;) {
        if (i < m && j < n) {
            arr[idx++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
        } else if (i < m) {
            arr[idx++] = nums1[i++];
        } else if (j < n) {
            arr[idx++] = nums2[j++];
        }
    }
    for (let i = 0; i < total; i++) nums1[i] = arr[i];
};
  • 时间复杂度:
  • 空间复杂度:

双指针 - 原地合并

上述两类做法都不是最优:

  • 要么使用到了“排序”操作,时间复杂度带 ,不是最优
  • 要么使用到了“额外辅助数组”空间,空间复杂度不为 ,也不是最优

那么是否有“不排序”且“不消耗额外空间”的原地做法呢?

答案是有的。

「使用两个指针 ij 分别指向 nums1nums2 的结尾位置,从后往前地原地构造出答案。」

所谓的原地构造是指:直接将 之间的较大值,放到合并后该在 nums1 出现的位置。

这也是为什么我们要「从后往前」而不是「从前往后」的原因。

使用 idx 代表当构造到答案的下标值,起始有 idx = m + n - 1(答案是一个长度为 的数组,因此下标是 ),根据指针 ij 所达位置,以及 大小关系,分情况讨论:

  • ij 任一到达边界,说明其中一个数组已用完,用另一数组的剩余元素进行填充即可
  • ij 均未到达边界,进一步比较 的大小关系:
    • ,说明在合并答案中 出现 后面,将 填入到 中,让 idxi 同时前移
    • 否则,将 填入到 中,让 idxj 同时前移

直到 ij 均到达边界,此时合并答案已全部填充到 nums1 中。

Java 代码:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m - 1, j = n - 1, idx = m + n - 1;
        while (i >= 0 || j >= 0) {
            if (i >= 0 && j >= 0) {
                nums1[idx--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--];
            } else if (i >= 0) {
                nums1[idx--] = nums1[i--];
            } else {
                nums1[idx--] = nums2[j--];
            }
        }
    }
}

C++ 代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = m - 1, j = n - 1, idx = m + n - 1;
        while (i >= 0 || j >= 0) {
            if (i >= 0 && j >= 0) {
                nums1[idx--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--];
            } else if (i >= 0) {
                nums1[idx--] = nums1[i--];
            } else {
                nums1[idx--] = nums2[j--];
            }
        }
    }
};

Python 代码:

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        i, j, idx = m - 1, n - 1, m + n - 1
        while i >= 0 or j >= 0:
            if i >= 0 and j >= 0:
                if nums1[i] > nums2[j]:
                    nums1[idx] = nums1[i]
                    i -= 1
                else:
                    nums1[idx] = nums2[j]
                    j -= 1
                idx -= 1
            elif i >= 0:
                nums1[idx] = nums1[i]
                idx, i = idx - 1, i - 1
            else:
                nums1[idx] = nums2[j]
                idx, j = idx - 1, j - 1

TypeScript 代码:

function merge(nums1: number[], m: number, nums2: number[], n: number): void {
    let i = m - 1, j = n - 1, idx = m + n - 1;
    while (i >= 0 || j >= 0) {
        if (i >= 0 && j >= 0) {
            nums1[idx--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--];
        } else if (i >= 0) {
            nums1[idx--] = nums1[i--];
        } else {
            nums1[idx--] = nums2[j--];
        }
    }
};
  • 时间复杂度:
  • 空间复杂度:

最后

巨划算的 LeetCode 会员优惠通道目前仍可用 ~

使用福利优惠通道 leetcode.cn/premium/?promoChannel=acoier,年度会员 有效期额外增加两个月,季度会员 有效期额外增加两周,更有超大额专属 🧧 和实物 🎁 福利每月发放。

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

欢迎关注,明天见。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值