我觉得这道题完全可以出难一点,可以返回有哪些数字重复了,分别重复了几次
经评论区提醒,或许考察的是与面试官的沟通能力,对不同解法的衡量取舍:
比如时间优先可以用 set 轻松解决,也只需要一次遍历,如果是进阶要求可以用hashmap记录次数,再遍历map输出
O(1)空间复杂度就原地排序,然后再遍历一遍输出第一个重复的,我第一个想到的是快排,当然也可以直接sort()
《剑指Offer》上给出的巧妙解法是利用数组下标和交换,当然这里的前提是所有数字都在 0~n-1 的范围内
长度为 n 的数组,且所有数字的范围都在 0~n-1范围内,在没有重复的情况下,那么正好可以将每个数字和下标建立映射关系:数字==下标,且正好一一对应
但是,题目中是存在重复数字的,而且不知道有几个数字是重复的,也不知道每个数字重复几次
所以,如果仍旧按照原本的映射关系来看,必然是有位置映射为空,有的位置映射2个或者2个以上
我们这么做:
- 遍历整个数组,通过交换位置来将映射关系建立起来,使数字一一归位
- 检查 i 与 nums[i],如果相等说明i已经之它应在的位置了
- 如果不相等,说明需要移动,再检查 nums[i] 和 nums[nums[i]]
- 如果不相等,就交换,将i归位,放到他应该在的地方
- 如果相等,说明它应该在的位置已经有元素了,(而且不能是它本身),即:重复了
看起来效果很棒
int findRepeatNumber(vector<int>& nums) {
int res = nums[0];
int i = 0;
while (i < nums.size()) {
if (i != nums[i]) {
if (nums[nums[i]] != nums[i]) {
swap(nums[i], nums[nums[i]]);
}
else {
res = nums[i];
break;
}
}
else i++;
}
return res;
}
标签:遍历,数字,映射,nums,重复,Offer,数组
From: https://www.cnblogs.com/yaocy/p/17095012.html