判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。
位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。
示例代码如下:
package com.sitinspring;
/** *//**
* 数组重复探测,时间复杂度为O(n)
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-6-18-上午03:24:07
*/
public class DuplicatedArrayTest{
public static void main(String[] args){
int[][] arr={
{1,2,3,5,3,5,56,534,3,32},
{1,2,3,5},
{1,2,3,5,3,5},
{0,0,1,2,3,5,56,534,78,32},
};
for(int i=0;i<arr.length;i++){
System.out.print("数组:");
for(int temp:arr[i]){
System.out.print(temp+",");
}
System.out.print("中");
System.out.print(hasDuplicatedItem(arr[i])?"存在":"不存在");
System.out.print("重复元素.\n");
}
}
/** *//**
* 判断整形数组中是否有重复数据,时间复杂度为O(n)
* @param arr
* @return
*/
public static boolean hasDuplicatedItem(int[] arr){
// 扫描数组找最大值
int max=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
}
}
// 按最大值创建一个新数组
int[] bitArray=new int[max+1];
// 按值向新数组中添值,如value为3则bitArray[3]=1
for(int value:arr){
if(bitArray[value]!=0){
// 如果value指向的位置已经不是零,说明之前已经给这一块置1了,立即返回true表示数组有重复
return true;
}
else{
// value指向的位置是零,则置为1表示这一位已经有数存在了
bitArray[value]=1;
}
}
return false;
}
}
输出:
数组:1,2,3,5,3,5,56,534,3,32,中存在重复元素.
数组:1,2,3,5,中不存在重复元素.
数组:1,2,3,5,3,5,中存在重复元素.
数组:0,0,1,2,3,5,56,534,78,32,中存在重复元素.
题外话:
今天法国真是太背了,为它送行吧!但愿它能早日迎来一个新的齐达内。