你有没有想过,为什么很多企业明确规定不招外包呢?刚好我在网上就看到一网友发出了灵魂提问:为什么大家招聘这么忌讳有外包经历的人呢?对于这个问题,我还是很好奇大家的看法,毕竟弄懂后还可以避避坑。

大家的观点也是各不相同。有的网友也是一脸懵:“咱也不知道啊,之前公司招人,特地强调不要外包出身的。”

而有的网友来了句:“其实挺简单的,人太多了,总得有个筛子,外包就成了过滤网,就跟学历一样样的”

还有网友分析说,可能是怕责任心不高;另一厢觉得,外包都是底层执行;觉得外包确实不得行。

那么问题来了,外包经历到底好不好?我认为底层逻辑在于“心态”,如果你整天只想着打卡上下班,任务一做完就开始摸鱼,那自然不是啥好事儿。

资源分享

👉点击领取:最全Python资料合集

但话说回来,如果你有能力,有见识,外包经历又怎样?的确,一些公司会为了提高招聘效率而设置种种门槛。而这和学历要求有点像,但又不完全一样,因为如果你的简历足够亮眼,完全可以忽略这些所谓的“短板”。

下面分享一道大厂的算法题

今日算法题,来自LeetCode的第31题:下一个排列,很多大厂都考过,下面是我的算法思路及实现,让我们来看看吧。

下一个排列

算法题目

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

引言

在数学和计算机科学中,一个序列的排列是指其元素的一种组合或排列。如果序列中的元素是有序的,则该序列可以有多种排列方式。
"下一个排列"问题涉及找到给定序列的所有排列中,按照字典序排序后给定序列的下一个序列。这是一个在编程竞赛和面试中经常遇到的问题,了解其解决方案对于提高算法设计和编程技能非常有帮助。

算法思路

  1. 从后向前查找第一个相邻升序的元素对 (i, i+1),满足 A[i] < A[i+1]。这一步是为了找到需要进行交换的较小数。如果不存在这样的对,说明当前排列已经是最大的排列,跳到步骤4。

  2. 再次从后向前查找第一个大于A[i]的元素A[j],A[i]和A[j]交换位置。这一步是为了找到比较小数稍微大一点的数。

  3. 将A[i+1]之后的所有元素反转,因为在步骤1之后的序列一定是降序的,反转之后就能得到其最小的排列。

  4. 如果在步骤1中找不到这样的相邻升序元素对,将整个数组反转,得到其最小的排列。

代码实现

JavaScript实现

function nextPermutation(nums) {    let i = nums.length - 2;    while (i >= 0 && nums[i] >= nums[i + 1]) {        i--;    }    if (i >= 0) {        let j = nums.length - 1;        while (nums[j] <= nums[i]) {            j--;        }        [nums[i], nums[j]] = [nums[j], nums[i]];    }    let l = i + 1, r = nums.length - 1;    while (l < r) {        [nums[l], nums[r]] = [nums[r], nums[l]];        l++;        r--;    }}
Java实现
public void nextPermutation(int[] nums) {    int i = nums.length - 2;    while (i >= 0 && nums[i] >= nums[i + 1]) {        i--;    }    if (i >= 0) {        int j = nums.length - 1;        while (nums[j] <= nums[i]) {            j--;        }        int temp = nums[i];        nums[i] = nums[j];        nums[j] = temp;    }    int l = i + 1, r = nums.length - 1;    while (l < r) {        int temp = nums[l];        nums[l] = nums[r];        nums[r] = temp;        l++;        r--;    }}
Go实现
func nextPermutation(nums []int) {    i := len(nums) - 2    for i >= 0 && nums[i] >= nums[i+1] {        i--    }    if i >= 0 {        j := len(nums) - 1        for nums[j] <= nums[i] {            j--        }        nums[i], nums[j] = nums[j], nums[i]    }    for l, r := i+1, len(nums)-1; l < r; l, r = l+1, r-1 {        nums[l], nums[r] = nums[r], nums[l]    }}

算法解析

该算法的关键在于如何高效地找到所需交换的位置并完成序列的逆转,以达到字典序中的下一个排列。
该过程主要包括两个步骤:寻找交换位置和完成交换与逆转。整个算法的时间复杂度为O(n),其中n是数组的长度,空间复杂度为O(1),因为算法只需要常数空间来存储索引。

示例和测试

假设有一个数组 nums = [1,2,3],按照上述算法步骤:

  1. 从后向前找到第一个升序的元素对是 (2, 3),即 i = 1。

  2. 再次从后向前查找第一个大于1的元素是3,交换1和3的位置,得到 [1,3,2]。

  3. 由于 [3,2] 已经是 [2] 之后所有元素的逆序,不需要再做操作。

因此,下一个排列是 [1,3,2]。

总结

"下一个排列"问题是一个典型的算法问题,它不仅考察了对数组操作的熟练程度,还涉及到了对问题解决步骤的逻辑思考。通过实现和理解这一算法,可以加深对字典序排列以及数组操作技巧的理解,对于提高编程能力非常有帮助。

 
热门推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

搜索

标签列表