《剑指offer》面试题03. 数组中重复的数字
问题描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
这道题和leetcode 287. 寻找重复数相似:
代码1
时间复杂度\(O(N)\),空间复杂度\(O(N)\).
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int n = nums.size(),i;
vector<int> map(n,0);
for(i = 0; i< n; ++i)
{
++map[nums[i]];
if(map[nums[i]]>1)
break;
}
return nums[i];
}
};
结果:
执行用时 :116 ms, 在所有 C++ 提交中击败了17.01%的用户
内存消耗 :24 MB, 在所有 C++ 提交中击败了100.00%的用户
代码2
如果允许移动数据,时间复杂度为\(O(N\log(N))\),空间复杂度为\(O(1)\):
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int n = nums.size(),i;
sort(nums.begin(),nums.end());
for(i = 0; i < n-1; ++i)
{
if(nums[i] == nums[i+1])
break;
}
return nums[i];
}
};
结果:
执行用时 :132 ms, 在所有 C++ 提交中击败了12.97%的用户
内存消耗 :23.3 MB, 在所有 C++ 提交中击败了100.00%的用户
代码3
如果允许修改数据,时间复杂度为\(O(N)\),空间复杂度为\(O(1)\):
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int i,n = nums.size(),j;
for(i = 0; i < n; ++i)
{
j = abs(nums[i]);
if(nums[j] < 0)return j;
else nums[j] = -nums[j];
}
//因为一定有重复的数字,前面如果没有退出程序的话说明重复的是0
return 0;
}
};
结果:
执行用时 :92 ms, 在所有 C++ 提交中击败了28.16%的用户
内存消耗 :22.8 MB, 在所有 C++ 提交中击败了100.00%的用户
代码4
如果允许移动数据,时间复杂度为\(O(N)\),空间复杂度为\(O(1)\):
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int i,n = nums.size(),j;
for(i = 0; i < n; ++i)
{
//我不在该在的地方,我该在的地方不是我
while(nums[i] != i && nums[i] != nums[nums[i]])
swap(nums[i],nums[nums[i]]);
//我不在该在的地方,我该在的地方还有我
if(nums[i] != i && nums[i] == nums[nums[i]])
break;
}
return nums[i];
}
};
结果:
执行用时 :92 ms, 在所有 C++ 提交中击败了28.16%的用户
内存消耗 :23.1 MB, 在所有 C++ 提交中击败了100.00%的用户
代码5
如果不允许移动数据,不允许修改数据,时间复杂度为\(O(N\log(N))\),空间复杂度为\(O(1)\),注意不能简单的写为
int findRepeatNumber(vector<int>& nums) {
int i,n = nums.size(),left = 1,right = n,middle,num;
while(left < right)
{
middle=left+(right-left)/2;
cout<<"("<<left<<","<<middle<<","<<right<<")"<<endl;
num = 0;
for(i = 0; i < n; ++i)
if(nums[i]+1 <= middle)
++num;
cout<<" "<<num<<endl;
if(num <= middle)
left = middle+1;
else
right = middle;
}
return left-1;
}
};
反例[0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],上面的写法适宜于写\(n+1\)个在1到n之间的元素,即不缺元素,这个例子缺个5.正确写法待思考。
《剑指offer》面试题03. 数组中重复的数字的更多相关文章
- 【Java】 剑指offer(1) 找出数组中重复的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...
- 【剑指Offer】50、数组中重复的数字
题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果 ...
- 剑指offer(50)数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- 剑指offer五十之数组中重复的数字
一.题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- 【剑指Offer】面试题03. 数组中重复的数字
题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意 ...
- 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...
- 剑指offer第二版-3.数组中重复的数
面试题3:数组中重复的数 题目要求: 在一个长度为n的数组中,所有数字的取值范围都在[0,n-1],但不知道有几个数字重复或重复几次,找出其中任意一个重复的数字. 解法比较: /** * Copyri ...
- 剑指offer 面试题 删除链表中重复的节点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 剑指offer 面试题56. 数组中只出现一次的两个数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...
随机推荐
- OpenWrt之DNS设置
目录 OpenWrt之DNS设置 0.前言 1.WAN口 2.Lan口 3.LAN口DHCP选项 4.DHCP/DNS 5.总结 参考(Thanks) 附录.DHCP OPTION OpenWrt之D ...
- Python 线程池模块threadpool 、 concurrent.futures 的 ThreadPoolExecutor
一.threadpool 基本用法 pip install threadpool pool = ThreadPool(poolsize) requests = makeRequests(some_ ...
- Android 控件使用教程(二)—— RecyclerView 展示图片
简介 在上一篇博文中,介绍了大家已经很熟悉的布局控件ListView,在这篇文章中,我将使用比较新.功能也更强大的RecyclerView. RecyclerView 首先,要用这个控件,你需要在gr ...
- 【LeetCode】459. Repeated Substring Pattern 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历子串 日期 [LeetCode] 题目地址:ht ...
- 1033 - Generating Palindromes
1033 - Generating Palindromes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit ...
- Centos/Docker/Nginx/Node/Jenkins 操作
Centos Centos 是一个基于 Linux 的开源免费操作系统 # 本地拷贝文件到远程服务器scp output.txt root@47.93.242.155:/data/ output.tx ...
- JS事件冒泡与事件捕获怎么理解?
在js中存在事件冒泡与事件捕获两种概念,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题. 事件冒泡(dubbed bubbling) 事件冒泡我们从字面意思理解就是当用户行为触发我们页面的定 ...
- 《手把手教你》系列技巧篇(五十三)-java+ selenium自动化测试-上传文件-上篇(详细教程)
1.简介 在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等.所以宏哥打算按上传文件的分类对其进行一下讲解和分享. 2.为什么selenium没有提供 ...
- Hadoop编译打包记录
Hadoop编译打包,基于2.7.2版本的源码. # 打包过程中需要使用到的工具 java -version mvn -version ant -version type protoc type cm ...
- Swoole 中使用 Atomic 实现进程间无锁计数器
使用示例: $atomic = new Swoole\Atomic(); $serv = new Swoole\Server('127.0.0.1', '9501'); $serv->set([ ...