打印出数组重复的数字/数值个数

题目: 有一个长度为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));
			}
		}
	}

总结:

如果对空间复杂度没有要求,从代码可读性来看,建议使用第一种方法。

否则,建议使用第二种方法。

注:

判断数组是否有重复的数字,不要求打印重复次数,可参考判断数值是否有重复的数字

猜你喜欢

转载自blog.csdn.net/shi2huang/article/details/80046866
今日推荐