一个简单的数组面试题

2018-08-17 23:25:04 +08:00
 zmxnv123

今天晚上面试,有一个数组的题。 一个大小为 n 的数组,数组的内容为 1~n 的任意数,这些数中有一个数出现了 1 次,其他数出现 0 次或多次,怎么在 O(n)时间复杂度,O(1)空间复杂度内找到这个出现 1 次的数? 有没有大佬来解释一下?

5337 次点击
所在节点    C
41 条回复
feather12315
2018-08-17 23:27:25 +08:00
刚刚牛客网上面看到了类似的题目,不过有个限制:数的大小限制在 0-n-1,这题目名称为:数组中重复的数字
zmxnv123
2018-08-17 23:30:55 +08:00
@feather12315 方便给个链接吗
1423
2018-08-17 23:34:23 +08:00
其他数出现 0 次或多次?不是偶数次?
qiuqiuer
2018-08-17 23:36:08 +08:00
每个出现了 1 次?
wbing
2018-08-17 23:37:35 +08:00
如果其他数是 0 次或偶数次的话,就全部异或一遍,剩下的那个
zmxnv123
2018-08-17 23:41:34 +08:00
@1423 对的 不是偶数次
dtgio
2018-08-17 23:45:13 +08:00
用 unordered_map 记录每个数出现的次数?
rabbbit
2018-08-17 23:49:17 +08:00
数组是有序的吗?
crayygy
2018-08-17 23:50:54 +08:00
异或
feather12315
2018-08-17 23:59:25 +08:00
ppyybb
2018-08-17 23:59:40 +08:00
这样做,从头扫描数组
对于 a[i] = x,
如果 i==x,那么直接下一个
否则,和 a[x]的绝对值比较,如果不等,就进行交换。
如果相等,就代表找到一个重复出现的数字,这时候把数字取反得到负数。
然后继续当前位置,如果数字是 n,就记录到一个单独变量里面(额外的一个空间)。
最后这个数组里面的唯一正数就是答案。

时间复杂度很容易说明,每一次要不前进,要不就交换,而每次交换都会将一个数字放到原本的位置上,所以是 o ( n )
innoink
2018-08-18 00:03:38 +08:00
这就是数据可以当下标用的一个地方
zmxnv123
2018-08-18 00:11:19 +08:00
@ppyybb 好像可以 明天试一下
ppyybb
2018-08-18 00:12:18 +08:00
@zmxnv123 有些细节没写全哦,但是大概思路应该可以
Daath
2018-08-18 00:48:17 +08:00
堆排序了解一下
Mirana
2018-08-18 00:55:27 +08:00
把数字 N 放在数组对应的下标上 Array[N-1]
zheyu
2018-08-18 01:13:05 +08:00
第一遍遍历把数字 i 放在 a[i-1]上,第二遍遍历对 a[i-1]!=i 的地方,令 a[a[i-1]]=0,第三遍遍历找到 a[i-1]==i 的值。这个 i 应该就是只出现一次的数字了
wenzhoou
2018-08-18 05:30:54 +08:00
简单的再开一个数组,记录每个数字出现的次数。然后再遍历一遍,找到次数为 1 的数字。
l30n
2018-08-18 07:25:53 +08:00
利用原来数组的空间
daozhihun
2018-08-18 08:03:53 +08:00
@wenzhoou 空间要求为 1,不能开数组

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/480886

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX