数组中重复的数字

Posted by DH on July 24, 2017

题目

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。 也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

分析

(1)直接想到的可以使用hashmap,遍历一次,时间复杂度是O(n),空间复杂度是O(n);

(2)可以使用排序,排序后遍历,比较前后两个数是否相同,时间复杂度是O(nlogn);

(3)使用一个Boolean数组存储,遍历原整数数组,将原数组对应元素的值隐射成Boolean数组的下标,并存储成true。

为啥要用这个数组呢?

1.boolean不是占1位,计算机处理处理数据的最小单元是1字节,一般1位的话,其余7位会被0补齐。

2.在java虚拟机规范中,JVM没有用于操作boolean的字节码指令,在编译后用int的数据类型代替boolean,此时boolean占4字节。

3.boolean[]数组编译后会被byte[]数组代替,此时的boolean占1字节。

总结:boolean单独存在占4字节,在boolean[]中占1字节!

这是网友的解答,所以用Boolean可以减少内存的使用。

代码

我使用第三种方法结题,代码如下:

public class Solution {
    // Parameters:
    //    numbers:     an array of integers
    //    length:      the length of array numbers
    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    //    这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    public boolean duplicate(int numbers[],int length,int [] duplication) {
    	 if (numbers== null || length == 0) {
			return false;
		}
	     
	     boolean [] tempBooleans = new boolean[length];
	     
	     for(int i =0;i< length;i++){
	    	 	
	    	 // 将numbers数组的元素作为数组的下标,出现过的元素对应的下标存储true
	    	 	
				if (tempBooleans[numbers[i]]== true) {
					duplication[0] = numbers[i];
					return true;
				}
				
				
				tempBooleans[numbers[i]] = true;
	    	 
	     }
	     
	     return false;
    }
}