题目描述:在一个长度为n的数组里所有数字都在0~n-1范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
分析:
解法一:先排序,再找出重复的数字,可以找出所有重复的数字。
代码如下:
public sealed class SortAndFind
{
//快排的单元排序
private static int SortInit(int[] arr, int low, int high)
{
int key = arr[low];
while (low < high)
{
while (arr[high] >= key && high > low)
high--;
arr[low] = arr[high];
while (arr[low] <= key && low < high)
low++;
arr[high] = arr[low];
}
arr[low] = key;
return low;
}
//快排
private static void QuickSort(int[] arr, int low, int high)
{
if (low >= high)
return;
int index = SortInit(arr, low, high);
QuickSort(arr, low, index - 1);
QuickSort(arr, index + 1, high);
}
//找出所有重复的数字
public static int[] FindRepeatNums(int[] arr)
{
List<int> temp = new List<int>();
QuickSort(arr, 0, arr.Length - 1);
foreach (int item in arr)
{
Console.Write("{0} ", item);
}
Console.WriteLine();
for (int i = 0; i < arr.Length - 1; i++)
{
if (arr[i] != arr[i + 1])
continue;
while (arr[i] == arr[i + 1] && i < arr.Length - 2)
{
i++;
}
temp.Add(arr[i]);
}
int[] result = temp.ToArray();
return result;
}
}
解法二:使用字典存储值和值的数量,可以找出所有重复的数字。
代码如下:
public sealed class DictionaryAndFind
{
public static void Find(int[] arr)
{
Dictionary<int, int> dictionary = new Dictionary<int, int>();
for (int i=0;i<arr.Length;i++)
{
if (!dictionary.ContainsKey(arr[i]))
dictionary.Add(arr[i], 1);
else
dictionary[arr[i]] += 1;
}
int[] keys = dictionary.Keys.ToArray();
for(int j = 0;j<keys.Length;j++)
{
if (dictionary[keys[j]] > 1)
Console.Write("{0} ", keys[j]);
}
}
}
解法三:仔细分析题目,所有数字都在0~n-1范围内,抓住这个条件,我们可以想假如没有重复的数会怎么样?排好序的话下标与值相等,根据这个来解。假如值等于下标,则往后扫描,否则,先与下标为该值的值比较,若相等,则找到了重复的数,否则,交换两个数。一边排序,一边找重复的数。
代码如下:
public sealed class ChangeAndFind
{
public static int FindOneRepeat(int[] arr)
{
if (arr == null || arr.Length <= 0)
return -1;
for(int i=0;i<arr.Length;i++)
{
if (arr[i] < 0 || arr[i] > arr.Length - 1)
return -1;
}
int one = 0;
for(int i=0;i<arr.Length;i++)
{
while(arr[i]!=i)
{
int temp = arr[i];
if (arr[i] == arr[temp])
{
one = arr[i];
return one;
}
arr[i] = arr[temp];
arr[temp] = temp;
}
}
return one;
}
}
总结:要仔细分析题目,从而找出最优解。