题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解题思路
本题目用了两种方法进行解题,首先是之前比较熟悉的快慢指针方法,对数组进行快排后再用快慢指针比较,不作过多阐述,代码如下
//快慢指针法
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
int findRepeatNumber(vector<int>& nums)
{
int slow = 0;
int fast = 1;
//快排升序
sort(nums.begin(), nums.end());
while (fast != nums.size())
{
if (nums[fast] == nums[slow])
{
return nums[slow];
}
nums[++slow] = nums[fast++];
}
return -1;
}
};
第二种思路是鲁棒性较高的方法,由于题目中已知是一个长度为n内容在0-n-1区间内的数组,就可以用数组下标和内容对齐的办法进行检验,从前之后将每个数组内容于下标不符合的进行归位,若归为途中找到了目标位置上的元素和下标相等的情况就是重复元素,代码如下
//采用鲁棒的方法
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
int findRepeatNumber(vector<int>& nums)
{
//考虑鲁棒,当数组长度小于等于1时显然不会有重复
if (nums.size() <= 1) return -1;
//考虑鲁棒,当数组中出现元素大于n-1或者<0时退出
for (int i = 0; i < nums.size(); i++)
{
if (nums[i] > nums.size() - 1 || nums[i] < 0)
return -1;
}
for (int i = 0; i < nums.size(); i++)
{
while(nums[i] != i)
{
if (nums[nums[i]] == nums[i])return nums[i];
//交换num[i]和nums[nums[i]]
int imp = nums[nums[i]];
nums[nums[i]] = nums[i];
nums[i] = imp;
/*nums[nums[i]] = nums[i] + nums[nums[i]];
nums[i] = nums[nums[i]] - nums[i];
nums[nums[i]] = nums[nums[i]] - nums[i];*/
}
}
return -1;
}
};
ps:在写代码过程中对俩元素交换采用了算术运算的方法避免出现临时变量,但是用以后发现陷入了无限循环,才发现是因为num[i]发生改变后nums[nums[i]]的位置也会因此发生改变,所以这里我们还是要引入临时变量(也可以临时变量存num[i]再用算术运算,但是没必要)