leetcode 217. Contains Duplicat hash解法及相关hashmap与hashset问题
2016-07-10 15:05
435 查看
对于leetcode271题来说,当用hash的思路来解决时(当然有更快的方法,方法 一),发现用Set实现ok,用Map实现就会出现超时。
方法一:
以上两程序,一个用Set,一个用Map。而HashSet的实现是建立在HashMap上的。具体到本程序中。add()调用的是put()
但是连个类中的contains()实现原理却大为不同。HashTable中:
每次都要遍历table数组。
再看HashSet中的contains()
直接通过索引找到table中的位置。而hashset的contains调用的是hashmap的containskey,所以此处调用hashmap然后调用containsKey同样可以通过。
由于put中都是用的索引直接定位,所以而已根据put的返回值来判断是否添加成功。
例如
方法一:
public boolean containsDuplicate(int[] nums) { Arrays.sort(nums); int len=nums.length; for(int i=0;i<len-1;i++) if(nums[i]==nums[i+1]) return true; return false; }
import java.util.Hashtable; public class Solution { public boolean containsDuplicate(int[] nums) { Hashtable <Integer,Integer>ht=new Hashtable<Integer,Integer>(); for(int i:nums) { if(ht.contains(i)) return true; ht.put(i); } return false; } }
import java.util.HashSet; public class Solution { public boolean containsDuplicate(int[] nums) { Set <Integer>ht=new HashSet<Integer>(); for(int i:nums) { if(ht.contains(i) return true; ht.add(i); } return false; } }
以上两程序,一个用Set,一个用Map。而HashSet的实现是建立在HashMap上的。具体到本程序中。add()调用的是put()
private static final Object PRESENT = new Object(); public boolean add(E e) { return map.put(e, PRESENT)==null; }
但是连个类中的contains()实现原理却大为不同。HashTable中:
public synchronized boolean contains(Object value) { if (value == null) { throw new NullPointerException(); } Entry tab[] = table; for (int i = tab.length ; i-- > 0 ;) { for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) { if (e.value.equals(value)) { return true; } } } return false; }
每次都要遍历table数组。
再看HashSet中的contains()
public boolean contains(Object o) { return map.containsKey(o); } 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; }
直接通过索引找到table中的位置。而hashset的contains调用的是hashmap的containskey,所以此处调用hashmap然后调用containsKey同样可以通过。
由于put中都是用的索引直接定位,所以而已根据put的返回值来判断是否添加成功。
例如
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i : nums) { if (map.put(i, i) != null) return true; } return false; public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
相关文章推荐
- c语言实现hashmap(转载)
- Ruby中Hash的11个问题解答
- Ruby简明教程之数组和Hash介绍
- 在C#中生成与PHP一样的MD5 Hash Code的方法
- js中hash和ico的关联分析
- 详解JavaScript中Hash Map映射结构的实现
- Javascript SHA-1:Secure Hash Algorithm
- JS hashMap实例详解
- 理解php Hash函数,增强密码安全
- 解析WeakHashMap与HashMap的区别详解
- 全面解析Java中的HashMap类
- Ruby中Hash哈希结构的基本操作方法小结
- PHP利用hash冲突漏洞进行DDoS攻击的方法分析
- PowerShell中定义哈希散列(Hash)和调用例子
- Redis String 类型和 Hash 类型学习笔记与总结
- php操作redis中的hash和zset类型数据的方法和代码例子
- 基于Java HashMap的死循环的启示详解
- Perl 哈希Hash用法之入门教程
- perl哈希hash的常见用法介绍
- HashMap总结