8.Contains Duplicate

leetcode原题如下:

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

分析:这个题目是要求输入为一个整型数组,判断输入的数组中是否有元素重复,若有则返回true,如果没有则返回false。

比较快的速度就是在遍历数组的过程中,先判断该数组是否在集合中若在则返回true,如不在则把数组元素放到集合中,接着遍历数组元素。

如果数组已经遍历结束还没有找到重复的元素,则说明数组中没有重复的元素,返回false即可。

在第一次实现的时候我用了ArrayList来存储元素,但是提交之后回馈信息是运行超时。这部分代码如下:

 public boolean containsDuplicate(int[] nums) {
		 ArrayList<Integer> list = new  ArrayList<Integer>();
		 int totalnum = nums.length;
		 int i=0;
		 long start = System.currentTimeMillis();
		 for(;i<totalnum;i++){
			 if(list.contains(nums[i])){
				 return true;
			 }else{
				 list.add(nums[i]);
			 }
		 } 
		 long end = System.currentTimeMillis();
		 System.out.println((end-start)+"ms");
	        return false;
	    }

然后继续修改代码,变成用map存储。提交到leetcode之后通过。这部分代码如下:

 public boolean containsDuplicate(int[] nums) {
		HashMap<Integer,Integer> h = new HashMap<Integer,Integer>();
		 int totalnum = nums.length;
		 int i=0;
		 long start = System.currentTimeMillis();
		 for(;i<totalnum;i++){
			 if(h.containsKey(nums[i])){
				 return true;
			 }else{
				 h.put(nums[i], i);
			 }
		 }
		 long end = System.currentTimeMillis();
		 System.out.println((end-start)+"ms");
	        return false;
	    }
这两个方法均用含有30000个元素的数组测试之后

 public static void main(String[] args){
		 int[] nums = new int[30000];
		 for(int i=0;i<30000;i++){
			 nums[i]=i;
		 }
		 ContainsDuplicate test = new ContainsDuplicate();
		 boolean result = test.containsDuplicate2(nums);
		 System.out.println("result = "+result);
	 }

测试结果发现用list的运行时间是1023ms,用map的时候运行时间只有46ms。使用map判断某个元素是否存在比用list的效率要高出很多。

随后我看了下list与map查找某个元素是否存在的代码。

首先list查找某个元素是否存在的过程中依次从第一个存储的元素进行比较看是否有相等元素,相关源代码如下:

 public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

而map判断某个关键字是否存在,则是用了hash表的技术。map是一个很常用的功能,那就是<key,value>的存储和查找功能。这种数据类型的实现原理就是通过哈希表进行快速查找。哈希表的基本原理就是原本无序的集合经过哈希算法被重新调整位置,排列成新序列,也就是hash table(与其说是表,不如说是某种数据结构的数组)

相关源代码如下:

public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }


final Entry<K,V> getEntry(Object key) {
        if (size == 0) {
            return null;
        }

        int hash = (key == null) ? 0 : hash(key);
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

最后附上看到的一篇介绍为什么map的查找效率较快的文章。http://blog.sina.com.cn/s/blog_6afeac500100z7m4.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值