思路一
利用一个hashset,当前数字如果在set中则返回当前该数字,如果没有,则加入set。直到找到第一个重复的数字!
代码
import java.util.HashSet;
/*
*
* 数组中重复的数字
*
* */
class Solution {
public int findRepeatNumber(int[] nums) {
HashSet<Integer> set=new HashSet<>();
int length=nums.length;
int ans=0;
for (int i = 0; i < length; i++) {
if (set.contains(nums[i]))
{
ans=nums[i];
break;
}
else
set.add(nums[i]);
}
return ans;
}
}
结果
暴力解法,没有什么技巧性,也可以用hashmap来实现,毕竟hashset底层是hashmap!
思路二
注意到题目中,所有的数字都在0-n-1之间,也就是说,假设这些数字没有重复,那么我们对其进行排序后,应该是一个下标和数字相同的数组。
我们从头到尾对其进行一个遍历,假设当前的数字与下标相同,那么我们就继续遍历下一个数字,假设当前数字m与下标不同,我们就去寻找当前的数字所对应的下标,假设nums[m]==m,那么我们找到了第一个重复的数字,如果nums[m]!=m,那么就交换当前数字m到对应的数组下标那里!
代码
/*
* 数组中重复的数字
* */
class Solution {
public int findRepeatNumber(int[] nums) {
int length=nums.length;
int ans=0;
for (int i = 0; i < length; ++i)
{
if (nums[i]!=i)//当前数字不属于当前位置(排序后)
{
if (nums[nums[i]]==nums[i])//当前数字对应下标已经存在对应的数字
{
ans=nums[i];
break;
}
else //交换当前数字到其对应的位置
{
int temp=nums[i];
nums[i]=nums[temp];
nums[temp]=temp;
}
}
}
return ans;
}
}
结果
这种就是比较巧妙的利用了数值的特征的这种结题思想,速度较快!
int temp=nums[i];
nums[i]=nums[nums[i]];
nums[nums[i]]=temp;
本来这里我使用这种写法,还以为是出现了什么内存取值的问题,突然很高兴似乎自己发现了一个什么bug,等到仔细一想,原来在第二行,nums[i]就已经被改变了。。。。。。。