题目: 有一个长度为n的数组,里面所有元素的值都为整数,且范围为0到n-1。请列出数组中整数元素出现的次数。
例:
输入数组:{ 1, 6, 5, 3, 12, 2, 3, 2, 0, 1, 7, 4, 5 }
打印:
1 2 6 1 5 2 3 2 12 1 2 2 0 1 7 1 4 1
方法有如下两种:
一、用一个额外的数组记录重复情况,因为元素的值不可能超过下标,所以可以把元素的值当作额外数组的下标,记录元素出现的次数。
代码如下:
public static void printDuplicatedCountByOtherArray(final int[] testArray) { if (testArray == null || testArray.length == 0) { return; } checkArrayFormat(testArray); int length = testArray.length; int[] duplicatedCount = new int[length]; for (int i = 0; i < length; i++) { duplicatedCount[testArray[i]] = duplicatedCount[testArray[i]] + 1; } for (int i = 0; i < duplicatedCount.length; i++) { if (duplicatedCount[i] != 0) { System.out.println(i + " " + duplicatedCount[i]); } } }
测试代码如下:
public static void main(String[] args) { int[] testArray = new int[] { 1, 6, 5, 3, 12, 2, 3, 2, 0, 1, 7, 4, 5 }; printDuplicatedCountByOtherArray(testArray); }
测试环境:JDK1.8.0_144,Java HotSpot(TM) 64-Bit Server VM,默认垃圾收集器为PS Scavenge+PS MarkSweep。
测试结果:
0 1 1 2 2 2 3 2 4 1 5 2 6 1 7 1 12 1
二、因为元素的值不可能超过下标,所以把元素值当作下标,修改下标对应的元素值加上数组长度,即可标记该值已经出现,通过元素值与数组长度的差值即可判断次数。
代码如下:
public static void printDuplicatedCountChangeArray(int[] testArray) { if (testArray == null || testArray.length == 0) { return; } checkArrayFormat(testArray); int length = testArray.length; for (int i = 0; i < length; i++) { int index = testArray[i]; while (index >= length) { index = index - length; } testArray[index] = testArray[index] + length; } for (int i = 0; i < length; i++) { int index = testArray[i]; while (index >= length) { index = index - length; } int count = 0; while (testArray[index] >= length) { testArray[index] = testArray[index] - length; count++; } if (count != 0) { System.out.println(index + " " + count); } } }
测试代码如下:
public static void main(String[] args) { int[] testArray = new int[] { 1, 6, 5, 3, 12, 2, 3, 2, 0, 1, 7, 4, 5 }; printDuplicatedCountChangeArray(testArray); }
测试环境:JDK1.8.0_144,Java HotSpot(TM) 64-Bit Server VM,默认垃圾收集器为PS Scavenge+PS MarkSweep。
测试结果:
1 2 6 1 5 2 3 2 12 1 2 2 0 1 7 1 4 1
校验元素值是否合法代码:
private static void checkArrayFormat(int[] testArray) { for (int i = 0; i < testArray.length; i++) { if (testArray[i] >= testArray.length || testArray[i] < 0) { throw new RuntimeException("The array value must be in 0-" + (testArray.length - 1)); } } }
总结:
如果对空间复杂度没有要求,从代码可读性来看,建议使用第一种方法。
否则,建议使用第二种方法。
注:
判断数组是否有重复的数字,不要求打印重复次数,可参考判断数值是否有重复的数字。