前言
找出數組中重複的數字。
在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。
示例 1:
輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3
限制:
2 <= n <= 100000
正文
下面是我的幾種解法:
我想到的就是字典:
public int FindRepeatNumber(int[] nums) {
Dictionary<int,int> dic=new Dictionary<int,int>();
foreach(var i in nums)
{
if(dic.ContainsKey(i))
{
return i;
}else
{
dic.Add(i,1);
}
}
return -1;
}
這種也是存在問題的,因爲Dictionary 是key 和value形式,value純屬浪費。
然後是數組:
public int FindRepeatNumber(int[] nums) {
int[] x =new int[nums.Length];
foreach(var i in nums)
{
x[i]++;
if(x[i]>1)
{
return i;
}
}
return -1;
}
但是一下子產生了數組,可能在一些情況下數組很多都浪費了。
那麼想到了集合
public class Solution {
public int FindRepeatNumber(int[] nums) {
HashSet<int> set = new HashSet<int>();
foreach (var i in nums)
{
if (!set.Add(i))
{
return i;
}
}
return -1;
}
}
最後我看了別人的。
public class Solution {
public int FindRepeatNumber(int[] nums) {
int temp;
for(int i=0;i<nums.Length;i++){
while (nums[i]!=i){
if(nums[i]==nums[nums[i]]){
return nums[i];
}
temp=nums[i];
nums[i]=nums[temp];
nums[temp]=temp;
}
}
return -1;
}
}
這種思路還是第一次見,然後主要在於審題,在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。
很巧妙,每次讓數字回到一個位置上,那麼下一個比較的就是和對應位置的數字做比較。可以畫一個圖。
畫的有點凌亂,但是大概就是這個意思,當時我考慮的是是否會出現無限循環,後來證實了不可能。
因爲這樣的,假如要形成無限循環的話,那麼nums[i]!=i就有不存在。
那麼除非是沒有這個數,否則一定會形成交叉。
那麼就在沒有這個數的情況下,只要有相等的那麼就會跳出循環。
那麼就在沒有這個數也沒有相等的情況下。
但是這種情況不可能,因爲:在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。