剑指offer 03.数组中的重复数字
剑指offer 03.数组中的重复数字
题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
链接:https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
题解
解法1:暴力循环
解法分析
使用双重循环,对每一个遍历到的元素,遍历其后的元素,判断是否与当前元素相等,若相等,直接返回,不相等继续查找直到找到相等情况或者遍历完数组。
边界条件与特殊值分析
- nums.size()==0,应当返回-1
- 数组中不存在重复值,应当返回-1
复杂度分析
时间复杂度 O(n^2)
空间复杂度 O(1)
代码
int findRepeatNumber(vector<int>& nums) {
//force
//复杂度 n^2
//使用双重循环,对每一个数寻找后面是否有相同项
for(int i=0;i<nums.size();i++)
{
for(int j=i+1;j<nums.size();j++)
{
if(nums[j]==nums[i])return nums[i];
}
}
return -1;
}
可能存在的问题
暂无
解法2:排序+遍历
解法分析
使用排序算法进行排序后,进行遍历,若nums[i]==nums[i+1],则返回nums[i],否则直到遍历到数组下标到达该数组长度为止。
排序算法使用复杂度为nlogn的算法,可以使用快速排序
边界条件与特殊值分析
- nums.size()==0,应当返回-1
- 数组中不存在重复值,应当返回-1
复杂度分析
时间复杂度 O(nlogn)
空间复杂度 O(n)
代码
int findRepeatNumber(vector<int>& nums) {
//sort & linear search
//待补充
return -1;
}
可能存在的问题
暂无
解法3:简易Hashmap
解法分析
因数组内元素大小在 [0,n-1] 范围内,故尝试使用长度为 n 的数组hash,以下标作为hashmap的key,将数组值作为出现次数,即value,形成键值对,遍历过程中,若 hash[num[i]]==0,则将hash[num[i]]+1,若hash[num[i]]=1,则返回重复值。
边界条件与特殊值分析
- nums.size()==0,应当返回-1
- 数组中不存在重复值,应当返回-1
复杂度分析
时间复杂度 O(n)
空间复杂度 O(n)
代码
int findRepeatNumber(vector<int>& nums) {
//hashmap
int sizeOfNums=nums.size();
vector<int>hash(sizeOfNums);
for(int i=0;i<sizeOfNums;i++)
{
if(hash[nums[i]]==1)return nums[i];
else hash[nums[i]]++;
}
return -1;
}
可能存在的问题
暂无
解法4:数组元素交换归位
解法分析
对于nums数组,进行遍历,对nums[i],若nums[i]==i,则进行下一位比较,否则,若nums[nums[i]]!=nums,交换nums[i]与nums[nums[i]],并就继续内循环判断,直到相等,否则,输出重复值,比如对于{2,3,1,0,2,5,3},进行推导尝试
边界条件与特殊值分析
- nums.size()==0,应当返回-1
- 数组中不存在重复值,应当返回-1
复杂度分析
时间复杂度 O(n)
空间复杂度 O(1)
代码
int findRepeatNumber(vector<int>& nums) {
//swap
for(int i=0;i<nums.size();i++)
{
while(nums[i]!=i)
{
if(nums[i]==nums[nums[i]])return nums[i];
else swap(nums[i],nums[nums[i]]);
}
}
return -1;
}
可能存在的问题
暂无