网易首页 > 网易号 > 正文 申请入驻

财大气粗的字节也开始裁员了。。。(内附飞书面试题解析)

0
分享至

前阵子看到一个令人关注的动态:飞书计划进行团队规模的优化调整,据悉,这一调整预计将影响大约1000名员工


飞书很好用,尤其是文档方面的功能,不仅免费,而且使用方便,所以我们团队的所有物料都存放在飞书里面,看到上面这个消息我们还是挺担心的,万一这次优化调整导致文档变得和石墨一样需要收费使用

现在只能静观其变,慢慢地迁移资料到本地,免得到时候限制导出就麻烦了。

来做一道和「飞书」相关的算法原题。


一、题目描述

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:

输入:nums = [1,3,4,2,2]
输出:2

示例 2:

输入:nums = [3,1,3,4,2]
输出:3

提示:

  • 1 <= n <= 105

  • nums.length == n + 1

  • 1 <= nums[i] <= n

  • nums只有一个整数 出现 两次或多次 ,其余整数均只出现 一次

进阶:

  • 如何证明 nums 中至少存在一个重复的数字?

  • 你可以设计一个线性级时间复杂度 O(n) 的解决方案吗?

二、题目解析

题目要求我们必须不修改数组 nums ,并且只用常量级 O(1) 的额外空间

一眼扫过去,题目很好理解,思路也很容易理清,最直观的想法就是使用哈希表不就能马上查找出重复的整数么

但再看一眼条件,只能用常量级 O(1) 的额外空间,于是哈希表的思路走不通。

一般的解法是采取二分查找的思路来解决,这里简单给大家介绍一下操作:

1、原始数组 nums 中总共包含了 n + 1 个整数,并且这些整数都在 [1, n] 范围内,那么如果设置 n 个抽屉,1 号抽屉存放 1 号整数、2 号抽屉存放 2 号整数、以此类推,那么总是有一个抽屉会至少存放两个数,这个数就是重复的数。


这个结论来自于抽屉原理:如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有 n + 1 个元素放到 n 个集合中去,其中必定有一个集合里至少有两个元素。

2、接下来,设置两个指针, left 指向最小值 1,right 指向最大值 nums.length - 1,以上图为例,此时 left = 1right = 4


3、取 left 和 right 的中间值 mid = ( left + right ) / 2 ,所有的抽屉被划分为两块区间,[ left , mid ] 和 [ mid + 1 , right ],如果我们知道重复数字会出现在其中一块区间,那么另外一块区间根本不需要去管,不用再去存放数字


4、统计原始数组 nums 中小于等于 mid 元素的个数 count,此时发现 count = 3,而 [ left , mid ] 只包含了两个抽屉,那么根据抽屉原理,必然会出现两个数挤在相同的抽屉里面。



5、因此,3 号抽屉、4 号抽屉无需再去考虑,只需要考虑 1 号抽屉、2 号抽屉,到底是哪个抽屉存放了重复的数。

6、此时,抽屉的范围发生了变化,由原来的 [ 1 , 4 ] 变成了 [ 1 , 2 ],即 left 不变,right 变成了 2。


7、接下来,继续将 left 和 right 的区间划分为两块区间,[ 1 , 1 ] 和 [ 2 , 2 ],此时,mid = 1 ,统计原始数组 nums 中小于等于 mid 元素的个数 count,发现 count = 1,说明 [ 1 , 1 ]这个区间只有一个抽屉一个整数,那么肯定不存在重复的数,重复的数在 [ 2 , 2 ] 这个区间。

8、此时,抽屉的范围发生了变化,由原来的 [ 1 , 2 ] 变成了 [ 2 , 2 ],即 right 不变,left 变成了 2。

9、当前区间只有一个抽屉,也就说明是这个抽屉存放了重复的数,抽屉的编号是 2,说明重复的数字就是 2,找到答案了。

代码如下:


def find_duplicate(nums): left = 1 right = len(nums) - 1
while left < right: mid = (left + right) // 2 count = 0
for num in nums: if num <= mid: count += 1
if count > mid: right = mid else: left = mid + 1
return left

由此,这道题目也就解决了。

这道题出在LeetCode,据说传奇大师 Don E.Knuth 花了 24 小时才解出来。这……不至于吧?难道还有什么坑我们没注意到?

问题出在优化!

二分查找解决的代码时间复杂度是O(nlogn),在面试的时候,面试官会问:还能不能再优化一下呢?

比如,LeetCode 的留言区就有同学懊恼的记录:今天美团面试考了这道题。作出一个解法以为完事了,结果连着追问好几种,整出翔了。


如果执着于二分查找的思路去优化,答案是无果,优化的方向是使用快慢指针。

具体操作如下:

1、对于原始数组 nums 来说,每个数字都有其对应的唯一索引 index,对于每个 index ,可以将其所对应的数字作为它下一个指向的对象,将这些对象串联为链表的形式。


2、比如先选 index = 0 作为链表的起始位置,那么 index = 0 在原始数组 nums 中的对象是 1 ,因此 0 --> 1 。


3、index = 1 在原始数组 nums 中的对象是 3 ,因此 1 --> 3 ,和前面串联起来就是 0 --> 1 --> 3 。


4、index = 3 在原始数组 nums 中的对象是 2 ,因此 3 --> 2 ,和前面串联起来就是 0 --> 1 --> 3 --> 2 。


5、index = 2 在原始数组 nums 中的对象是 4 ,因此 2 --> 4 ,和前面串联起来就是 0 --> 1 --> 3 --> 2 --> 4 。


6、index = 4 在原始数组 nums 中的对象是 2 ,因此 4 --> 2 ,和前面串联起来就是 0 --> 1 --> 3 --> 2 --> 4 --> 2 。


7、在上述的图中,链表中出现了一个环,因为 index = 3 和 index = 4 的对象 nums[3] 和 nums[4] 都等于 2。

8、链表中环的入口就是那个重复的数,那么这道题目也就变成了寻找环入口的题目。

那就和 LeetCode 第 142 号问题:环形链表II 的解法一模一样了。

1、通过快慢指针的方式,在环中寻找它们的第一次相遇的节点位置

2、当快慢指针相遇的时候:


x 代表从头节点到环形入口节点的节点数(不包含头节点)

y 代表从环形入口到第一次相遇节点的节点数(不包含环形入口节点)

z 代表从第一次相遇节点到环形入口的节点数(不包含第一次相遇节点)

此时,快指针走了 x + y + n (y + z),其中,x + y 表示快指针第一次到达相遇节点,n 代表快指针在环里面绕了多少圈。

而慢指针走了 x + y 步。

那么就出现了一个等式 x + y = [x + y + n (y + z)] / 2,即x = n(y + z)- y

n(y + z)- y 代表的含义是一个指针从相遇节点开始出发,走了 n 圈之后回到原来的出发位置,往后退 y 步

由于 x 代表从头节点到环形入口节点的节点数,并且x = n(y + z)- y,所以n(y + z)- y 代表的含义就是一个指针从相遇节点开始出发,走了 n 圈之后回到原来的出发位置,往后退 y 步来到了环的入口位置

那么,我们就可以设置两个指针,一个从链表的头节点开始出发,一个指针从相遇节点开始出发,当它们相遇的时候,代表着环的入口节点找到了。

三、参考代码

def find_duplicate(nums): # 1、通过快慢指针的方式,在环中寻找它们的第一次相遇的节点位置
# 2、定义一个慢指针,每次只会向前移动 1 步 slow = 0
slow = nums[slow]
# 3、定义一个快指针,每次只会向前移动 2 步 fast = 0
fast = nums[nums[fast]]
# 4、如果链表有环,那么无论怎么移动,fast 指向的节点都是有值的 while slow != fast: # 慢指针每次只会向前移动 1 步 slow = nums[slow] # 快指针每次只会向前移动 2 步 fast = nums[nums[fast]]
# 定义两个指针,一个指向相遇节点,定义为 b,一个指向链表头节点,定义为 a # 一个指向相遇节点,定义为 b b = fast
# 一个指向链表头节点,定义为 a a = 0
# 让 a 、b 两个指针向前移动,每次移动一步,直到相遇位置 # 由于有环,必然相遇 # 当 b 走了 n(y + z) - y 时,b 到达了环形入口节点位置 # 当 a 走了 x 步时,a 到达了环形入口节点位置 # a 与 b 相遇 while a != b: # a 指针每次只会向前移动 1 步 a = nums[a] # b 指针每次只会向前移动 1 步 b = nums[b]
# 6、返回 a 和 b 相遇的节点位置就是环形入口节点位置 return a

作者:吴师兄

来源:吴师兄学算法

Crossin的新书《码上行动:用ChatGPT学会Python编程》已经上市了。 本书以ChatGPT为辅助,系统全面地讲解了如何掌握Python编程,适合Python零基础入门的读者学习。

购买后可加入读者交流群,Crossin为你开启陪读模式,解答你在阅读本书时的一切疑问。

Crossin的其他书籍:

添加微信 crossin123 ,加入编程教室共同学习 ~


感谢 转发点赞 的各位~

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
代言人?沃克喜提新车——比亚迪海豹国外售价超40万人民币

代言人?沃克喜提新车——比亚迪海豹国外售价超40万人民币

直播吧
2024-05-01 23:16:35
终于,今年 618 要彻底变了!

终于,今年 618 要彻底变了!

果粉俱乐部
2024-04-30 12:06:34
凯伦威尔逊9-7希金斯!1/4决赛第二阶段结束

凯伦威尔逊9-7希金斯!1/4决赛第二阶段结束

小鬼头体育
2024-05-02 00:16:29
TVB女星再晒性感穿着,疑似真空视帝老公不满:又被人说啦

TVB女星再晒性感穿着,疑似真空视帝老公不满:又被人说啦

我爱追港剧
2024-04-29 23:30:50
Pura 70海外首拆来了:日媒拆了5年华为手机,得出一个结论

Pura 70海外首拆来了:日媒拆了5年华为手机,得出一个结论

三叔科技说
2024-04-29 22:17:51
李尚福被免去国防部长,虎父无犬子,父亲竟和美国交过手

李尚福被免去国防部长,虎父无犬子,父亲竟和美国交过手

磊子讲史
2024-03-25 14:45:46
上海最新政策!2024年养老金将继续上涨,5月1日基础养老金有惊喜

上海最新政策!2024年养老金将继续上涨,5月1日基础养老金有惊喜

小毅讲历史
2024-04-30 20:41:58
自己的车报废了,为啥不能自己卖废铁?非要交笔钱让别人来处理?

自己的车报废了,为啥不能自己卖废铁?非要交笔钱让别人来处理?

户外小阿隋
2024-05-01 12:08:24
三个沐沐改口,思想一夜间遥遥领先:车门能打开,亲人因冲撞死亡

三个沐沐改口,思想一夜间遥遥领先:车门能打开,亲人因冲撞死亡

皖声微言
2024-04-30 18:18:42
小玥儿突然打电话,张兰回拨无人接听,细细揣摩可能和这些相关!

小玥儿突然打电话,张兰回拨无人接听,细细揣摩可能和这些相关!

郑丁嘉话
2024-05-01 10:19:50
河南新建大桥出现多个黑洞 ,官方回应惹争议,网友:没见过这样的

河南新建大桥出现多个黑洞 ,官方回应惹争议,网友:没见过这样的

钱多多多多
2024-05-01 21:57:16
神奇大逆转!冰美人神了:决胜盘2-5、15-40翻盘,对手愤怒狂摔拍

神奇大逆转!冰美人神了:决胜盘2-5、15-40翻盘,对手愤怒狂摔拍

大秦壁虎白话体育
2024-05-01 22:06:14
河南某地暂停小学教师招聘,厦门教师招聘无人报考,究竟为什么?

河南某地暂停小学教师招聘,厦门教师招聘无人报考,究竟为什么?

骅骏老师张
2024-04-30 08:43:01
辽宁一厂长邀15名歌厅舞女做客,喝完酒后,将15人冲进下水道

辽宁一厂长邀15名歌厅舞女做客,喝完酒后,将15人冲进下水道

莫问先生
2024-04-23 12:34:42
中央批准!985大学,迎女校长(副部长级)

中央批准!985大学,迎女校长(副部长级)

双一流高校
2024-04-30 17:45:18
毛家的祖坟的秘密,伟人的一生竟然与“虎”有着不解之缘!

毛家的祖坟的秘密,伟人的一生竟然与“虎”有着不解之缘!

心灵短笛
2024-04-18 15:27:33
大厂忙着踢皮球的时候也请看看脚下的人

大厂忙着踢皮球的时候也请看看脚下的人

关尔东
2024-04-29 00:13:21
“与辉同行”全员完成切割,董宇辉等9位主播名字全部去东方化

“与辉同行”全员完成切割,董宇辉等9位主播名字全部去东方化

校长侃财
2024-04-29 13:04:48
25张难得一见的照片,你从未见过的世界,看完眼界都提高了

25张难得一见的照片,你从未见过的世界,看完眼界都提高了

嘿哥哥科技
2024-04-29 01:04:24
男大学生诱骗多名女生“骑大马”,事后给250元!校方:基本属实

男大学生诱骗多名女生“骑大马”,事后给250元!校方:基本属实

鲁中晨报
2024-05-01 14:45:07
2024-05-02 01:12:49
Crossin的编程教室
Crossin的编程教室
简单有趣的python入门
381文章数 702关注度
往期回顾 全部

科技要闻

余承东卸任华为终端CEO 新任命为董事长

头条要闻

万科总裁:王石自动放弃千万退休金

头条要闻

万科总裁:王石自动放弃千万退休金

体育要闻

詹眉湖人:洛杉矶大型烟花秀

娱乐要闻

黄子韬被曝求婚徐艺洋 大量亲密照曝光

财经要闻

上财万字报告深度解读Q1经济

汽车要闻

预售2.89-3.49万 奔腾小马正式开启预售

态度原创

家居
数码
游戏
时尚
军事航空

家居要闻

心之所栖 黑白灰色系打造设计专属感

数码要闻

五一如何“满电”出行?充电设备大部分人都选错了!

天下二游丑立绘共十斗,FGO独占八斗

小长假必备!五一出游超适合的单品和搭配!

军事要闻

近距离看中国第三艘航母福建舰解缆起航

无障碍浏览 进入关怀版