题目描述:在一个长度为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; } }总结:要仔细分析题目,从而找出最优解。