03. 数组中重复的数字
一、题目描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3限制:
2 <= n <= 100000
二、解题思路
1、原地置换法
数组元素的 索引和值是 一对多的关系。 因此,可遍历数组并通过交换操作,使元素的索引与 值一一对应(即 nums[i]=i )。这样就能通过索引映射对应的值,起到与字典等价的作用。
nums[i] | 2 | 3 | 1 | 0 | 2 | 5 | 3 |
---|---|---|---|---|---|---|---|
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
算法流程:
①、判断vector容器是否为空;
②、初始值为 i=0开始遍历数组 nums :
③、判断nums[i]与i的关系,如果nums[i]=i ,则说明此数字已在对应索引位置,无需交换;如果不相等,则进行交换 temp = nums[nums[i]]; nums[nums[i]]=nums[i]; nums[i]=temp; 直到nums[i]=i; i+1进入下一次遍历;
④、如果nums[nums[i]]=nums[i] ,代表索引 nums[i] 处和索引 i 处的元素值都为 nums[i],即为我们要找的重复数字
复杂度分析:
时间复杂度 O(N): 遍历数组使用 O(N) ,每轮遍历的判断和交换操作使用 O(1);
空间复杂度 O(1): 使用常数复杂度的额外空间。
具体程序实现:
#include <iostream>
#include <vector>
using namespace std;
void printVecotr(vector<int>& v)
{
for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//使用原地置换法
class Solution {
public:
int findRepeatNumber(vector<int> nums)
{
//首先判断数组是否为空
if(nums.size() == 0)
{
return -1;
}
for(int i = 0;i< nums.size();i++)
{
while(nums[i]!=i)
{
if(nums[i]==nums[nums[i]])
{
return nums[i];
}
int temp = nums[nums[i]];
nums[nums[i]]=nums[i];
nums[i]=temp;
}
}
return -1;
}
};
int main()
{
vector<int> v1;
int a[] = {
2,3,1,0,2,5,3};
auto length = sizeof(a)/sizeof(a[0]);
for(int i = 0; i < length; i++)
{
v1.push_back(a[i]);
}
printVecotr(v1);
cout << length << endl;
Solution S;
auto num = S.findRepeatNumber(v1);
cout << num << endl;
return 0;
}
输出:
0 1 1 0 2 5 3
7
2
程序具体的实现流程:
①、i = 0, nums[0] = 2 != 0;进入交换:temp = nums[nums[0]] = 1, nums[nums[0] = nums[0] = 2,nums[0] = 1;
则数组顺序变为:{1,3,2,0,2,5,3}
②、i = 0, nums[0] = 1 != 0; 进入交换:temp = nums[nums[0]] = 3, nums[nums[0] = nums[0] = 1,nums[0] = 3;
则数组顺序变为:{3,1,2,0,2,5,3}
③、i = 0, nums[0] = 3 != 0; 进入交换:temp = nums[nums[0]] = 0, nums[nums[0] = nums[0] = 3,nums[0] = 0;
则数组顺序变为:{0,1,2,3,2,5,3}
④、此时有nums[0] = 0;nums[1] = 1;nums[2] = 2;nums[3] = 3;
⑤、i = 4, nums[4] = 2 != 4; 进入if判断:nums[4] = nums[nums[4]]) = 2,则返回2
参考链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/