使用位图法判断整形数组是否存在重复

 

判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。

位图法比较适合于这种情况,它的做法是按照集合中最大元素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 ,中存在重复元素.


题外话:
今天法国真是太背了,为它送行吧!但愿它能早日迎来一个新的齐达内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值