一个简单的数组面试题

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

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

5184 次点击
所在节点    C
41 条回复
snail1988
2018-08-18 10:48:44 +08:00
@ppyybb 你这样有个前提是必须有序,否则就是 log 级别的时间复杂度
smdbh
2018-08-18 11:26:06 +08:00
@ppyybb , 1 2 2 ?
XxxxD
2018-08-18 12:09:08 +08:00
python 里面有个 count ()的函数,for in 一遍,找出属于 1 的?
snail1988
2018-08-18 12:12:27 +08:00
利用固定偏移可以时间复杂度 O(n),空间 O(1) 下面贴一段 demo,没处理 数组 size 接近 int 极限的情况

int unique_number(int arr[], int n) {
for (int idx = 0; idx < n; ++idx) {
int i = (abs(arr[idx])%n?:n)-1;
if (arr[i] > 0) {
arr[i] = -arr[i];
}
else if (arr[i] < 0) {
arr[i] = arr[i] - n;
}
}
for (int idx = 0; idx < n; ++idx) {
if (arr[idx] < 0 && arr[idx] > -n) {
return idx+1;
}
}
return 0;
}
wenzhoou
2018-08-18 12:14:23 +08:00
不能开数组那就是上面说的异或了。
baelish
2018-08-18 12:14:45 +08:00
遍历第 1 次,A[A[i]] *= n
遍历第 2 次,if(A[i] > n && A[i] < n*n) return A[i]/n
baelish
2018-08-18 12:15:39 +08:00
* 换成 +
snail1988
2018-08-18 12:16:07 +08:00
sorry,少写了一等号

int unique_number(int arr[], int n) {
for (int idx = 0; idx < n; ++idx) {
int i = (abs(arr[idx])%n?:n)-1;
if (arr[i] > 0) {
arr[i] = -arr[i];
}
else if (arr[i] < 0) {
arr[i] = arr[i] - n;
}
}
for (int idx = 0; idx < n; ++idx) {
if (arr[idx] < 0 && arr[idx] >= -n) {
return idx+1;
}
}
return 0;
}
baelish
2018-08-18 12:40:15 +08:00
遍历第 1 次,A[A[i]] += n
遍历第 2 次,if(A[i] > n && A[i] < 2*n) return A[i]-n

这回就对了
ppyybb
2018-08-18 14:05:22 +08:00
@snail1988 显然不用,这题我做过....
ppyybb
2018-08-18 14:10:41 +08:00
@smdbh 真巧,这是我校验的第一个 case。按我的做法最后状态变成-2 1 -2,所以 1 是唯一的。
likers
2018-08-18 14:11:59 +08:00
@wenzhoou 其他数字是出现 0 或多次,不是偶数次,不能异或
sikariba
2018-08-18 14:27:15 +08:00
主楼跟你回复里贴的链接完全就是 2 道题啊。。
wenzhoou
2018-08-18 14:58:53 +08:00
@likers 你说的正确。
thedog
2018-08-18 15:14:11 +08:00
异或一把
snail1988
2018-08-18 15:14:21 +08:00
@ppyybb 如果最坏情况 你相当于要把一半的元素进行交换排序
snail1988
2018-08-18 15:16:44 +08:00
@ppyybb 又想了一下,这个排序相当于桶排序,是 O(n)的 那总体复杂度确实还是 O(n)
vandort
2018-08-18 15:49:12 +08:00
我有个正确却没什么意义的答案:用睡排序对数组进行排序,然后就很好找那个出现了一次的数了
zmxnv123
2018-08-18 21:13:57 +08:00
@所有人 LZ 已经知道正确方法了 感谢各位
lcj2class
2018-08-19 17:17:39 +08:00

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

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

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

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

© 2021 V2EX