zoukankan      html  css  js  c++  java
  • [Swift]LeetCode706. 设计哈希映射 | Design HashMap

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/10506126.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Design a HashMap without using any built-in hash table libraries.

    To be specific, your design should include these functions:

    • put(key, value) : Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value.
    • get(key): Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key.
    • remove(key) : Remove the mapping for the value key if this map contains the mapping for the key.

    Example:

    MyHashMap hashMap = new MyHashMap();
    hashMap.put(1, 1);          
    hashMap.put(2, 2);         
    hashMap.get(1);            // returns 1
    hashMap.get(3);            // returns -1 (not found)
    hashMap.put(2, 1);          // update the existing value
    hashMap.get(2);            // returns 1 
    hashMap.remove(2);          // remove the mapping for 2
    hashMap.get(2);            // returns -1 (not found) 

    Note:

      • All keys and values will be in the range of [0, 1000000].
      • The number of operations will be in the range of [1, 10000].
      • Please do not use the built-in HashMap library.

    不使用任何内建的哈希表库设计一个哈希映射

    具体地说,你的设计应该包含以下的功能

    • put(key, value):向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。
    • get(key):返回给定的键所对应的值,如果映射中不包含这个键,返回-1。
    • remove(key):如果映射中存在这个键,删除这个数值对。

    示例:

    MyHashMap hashMap = new MyHashMap();
    hashMap.put(1, 1);          
    hashMap.put(2, 2);         
    hashMap.get(1);            // 返回 1
    hashMap.get(3);            // 返回 -1 (未找到)
    hashMap.put(2, 1);         // 更新已有的值
    hashMap.get(2);            // 返回 1 
    hashMap.remove(2);         // 删除键为2的数据
    hashMap.get(2);            // 返回 -1 (未找到) 

    注意:

      • 所有的值都在 [1, 1000000]的范围内。
      • 操作的总数目在[1, 10000]范围内。
      • 不要使用内建的哈希库。

     484ms

     1 class MyHashMap {
     2     var arr: [Int]
     3     /** Initialize your data structure here. */
     4     init() {
     5         arr = []
     6     }
     7     
     8     /** value will always be non-negative. */
     9     func put(_ key: Int, _ value: Int) {
    10         if arr.count <= key {
    11             arr += Array(repeating: -1, count: key-arr.count + 1)
    12         }
    13         arr[key] = value
    14     }
    15     
    16     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    17     func get(_ key: Int) -> Int {
    18         if key >= arr.count {return -1}
    19         return arr[key]
    20     }
    21     
    22     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    23     func remove(_ key: Int) {
    24         if key >= arr.count {return}
    25         arr[key] = -1
    26     }
    27 }
    28 
    29 /**
    30  * Your MyHashMap object will be instantiated and called as such:
    31  * let obj = MyHashMap()
    32  * obj.put(key, value)
    33  * let ret_2: Int = obj.get(key)
    34  * obj.remove(key)
    35  */

    492ms

     1 class MyHashMap {
     2 
     3     var array = Array(repeating: -1, count: 1000000)
     4     /** Initialize your data structure here. */
     5     init() {
     6         
     7     }
     8     
     9     /** value will always be non-negative. */
    10     func put(_ key: Int, _ value: Int) {
    11       array[key] = value
    12     }
    13     
    14     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    15     func get(_ key: Int) -> Int {
    16       return array[key]
    17     }
    18     
    19     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    20     func remove(_ key: Int) {
    21       array[key] = -1
    22     }
    23 }

    496ms

     1 class MyHashMap {
     2 
     3     /** Initialize your data structure here. */
     4     typealias Pair = (key: Int, value: Int)
     5     let MAX_LENGTH = 10000
     6     var array: [[Pair]?]
     7     
     8     init() {
     9         array = Array(repeating: nil, count: MAX_LENGTH)
    10     }
    11     
    12     private func getIndex(_ key: Int) -> Int {
    13         return key % MAX_LENGTH
    14     }
    15     
    16     private func getPos(_ key: Int, _ bucketIndex: Int) -> Int {
    17         if let bucket = array[bucketIndex] {
    18             for i in 0..<bucket.count {
    19                 let pair = bucket[i]
    20                 if pair.key == key {
    21                     return i
    22                 }
    23             }
    24         }
    25         
    26         return -1
    27     }
    28     
    29     /** value will always be non-negative. */
    30     func put(_ key: Int, _ value: Int) {
    31         let index = getIndex(key)
    32         let pos = getPos(key, index)
    33         if array[index] != nil {
    34             if pos < 0 {
    35                 // key not exisiting
    36                 array[index]!.append((key,value))
    37             } else {
    38                 // update key with new value
    39                 array[index]![pos] = (key,value)
    40             }
    41         } else {
    42             // create a new bucket
    43             array[index] = [(key,value)]
    44         }
    45     }
    46     
    47     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    48     func get(_ key: Int) -> Int {
    49         let index = getIndex(key)
    50         let pos = getPos(key, index)
    51         if array[index] != nil && pos >= 0 {
    52             return array[index]![pos].value
    53         } 
    54         return -1
    55     }
    56     
    57     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    58     func remove(_ key: Int) {
    59         let index = getIndex(key)
    60         let pos = getPos(key, index) 
    61         if array[index] != nil && pos >= 0 {
    62             array[index]!.remove(at: pos)
    63         }
    64     }
    65 }

    Runtime: 500 ms
    Memory Usage: 20.5 MB
     1 class LinkedNode {
     2     var next: LinkedNode?
     3     var key: Int
     4     var val: Int
     5     
     6     init(_ key: Int, _ val: Int) {
     7         self.key = key
     8         self.val = val
     9     }
    10 }
    11 
    12 class MyHashMap {
    13     
    14     private var nodes: [LinkedNode?]
    15 
    16     /** Initialize your data structure here. */
    17     init() {
    18         nodes = Array(repeating: nil, count: 10000)
    19     }
    20     
    21     /** value will always be non-negative. */
    22     func put(_ key: Int, _ value: Int) {
    23         let index = hash(key)
    24         guard let node = nodes[index] else {
    25             nodes[index] = LinkedNode(key, value)
    26             return
    27         }
    28         
    29         var next: LinkedNode? = node
    30         var pre: LinkedNode? = nil
    31         while next != nil, next!.key != key {
    32             pre = next
    33             next = next?.next
    34         }
    35         
    36         if let next = next {
    37             next.val = value
    38         } else {
    39             pre?.next = LinkedNode(key, value)
    40         }
    41     }
    42     
    43     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    44     func get(_ key: Int) -> Int {
    45         let index = hash(key)
    46         guard let node = nodes[index] else {
    47             return -1
    48         }
    49         
    50         var next: LinkedNode? = node
    51         var pre: LinkedNode? = nil
    52         while next != nil, next!.key != key {
    53             pre = next
    54             next = next?.next
    55         }
    56         
    57         return next?.val ?? -1
    58     }
    59     
    60     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    61     func remove(_ key: Int) {
    62         let index = hash(key)
    63         guard let node = nodes[index] else {
    64             return
    65         }
    66         
    67         var next: LinkedNode? = node
    68         var pre: LinkedNode? = nil
    69         while next != nil, next!.key != key {
    70             pre = next
    71             next = next?.next
    72         }
    73         
    74         if let pre = pre {
    75             pre.next = next?.next
    76         } else {
    77             nodes[index] = next?.next
    78         }
    79     }
    80     
    81     private func hash(_ key: Int) -> Int {
    82         return key % 10000
    83     }
    84     
    85 }
    86 
    87 /**
    88  * Your MyHashMap object will be instantiated and called as such:
    89  * let obj = MyHashMap()
    90  * obj.put(key, value)
    91  * let ret_2: Int = obj.get(key)
    92  * obj.remove(key)
    93  */ 

    516ms

     1 class ListNode<T> {
     2     
     3     var value: T
     4     var next: ListNode<T>?
     5     
     6     init(value: T) {
     7         self.value = value
     8     }
     9 }
    10 
    11 struct KeyValue {
    12     var key: Int
    13     var value: Int
    14 }
    15 
    16 class MyHashMap {
    17     
    18     private var buckets = [ListNode<KeyValue>?](repeating: nil, count: 1000)
    19 
    20     /** Initialize your data structure here. */
    21     init() {
    22         
    23     }
    24     
    25     /** value will always be non-negative. */
    26     func put(_ key: Int, _ value: Int) {
    27         if let existingNodes = findNode(key: key) {
    28             existingNodes.node.value.value = value
    29         } else {
    30             let hash = getHash(key)
    31             
    32             let value = KeyValue(key: key, value: value)
    33             let newNode = ListNode<KeyValue>(value: value)
    34             newNode.next = buckets[hash % buckets.count]
    35             buckets[hash % buckets.count] = newNode
    36         }
    37     }
    38     
    39     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    40     func get(_ key: Int) -> Int {
    41         guard let existingNodes = findNode(key: key) else {
    42             return -1
    43         }
    44         return existingNodes.node.value.value
    45     }
    46     
    47     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    48     func remove(_ key: Int) {
    49         guard let existingNodes = findNode(key: key) else {
    50             return 
    51         }
    52         
    53         if let previous = existingNodes.previous {
    54             previous.next = existingNodes.node.next
    55         } else {
    56             // the key is the head
    57             let hash = getHash(key)
    58             buckets[hash % buckets.count] = existingNodes.node.next
    59         }
    60     }
    61     
    62     private func findNode(key: Int) -> (previous: ListNode<KeyValue>?, node: ListNode<KeyValue>)? {
    63         let hash = getHash(key)
    64         
    65         var previous: ListNode<KeyValue>? = nil
    66         var head = buckets[hash % buckets.count]
    67         while let _head = head {
    68             if _head.value.key == key {
    69                 return (previous,_head)
    70             }
    71             previous = head
    72             head = _head.next
    73         }
    74         
    75         return nil // didn't find this key in the bucket
    76     }
    77     
    78     private func getHash(_ key: Int) -> Int {
    79         return abs(key.hashValue)
    80     }
    81 }

    528ms

     1 class MyHashMap {
     2 
     3     /** Initialize your data structure here. */
     4     typealias Pair = (key: Int, value: Int)
     5     let MAX_LENGTH = 10000
     6     var array: [[Pair]?]
     7     
     8     init() {
     9         array = Array(repeating: nil, count: MAX_LENGTH)
    10     }
    11     
    12     private func getIndex(_ key: Int) -> Int {
    13         return key % MAX_LENGTH
    14     }
    15     
    16     private func getPos(_ key: Int, _ bucketIndex: Int) -> Int {
    17         if let bucket = array[bucketIndex] {
    18             for i in 0..<bucket.count {
    19                 let pair = bucket[i]
    20                 if pair.key == key {
    21                     return i
    22                 }
    23             }
    24         }
    25         
    26         return -1
    27     }
    28     
    29     /** value will always be non-negative. */
    30     func put(_ key: Int, _ value: Int) {
    31         let index = getIndex(key)
    32         let pos = getPos(key, index)
    33         if array[index] != nil {
    34             if pos < 0 {
    35                 // key not exisiting
    36                 array[index]!.append((key,value))
    37             } else {
    38                 // update key with new value
    39                 array[index]![pos] = (key,value)
    40             }
    41         } else {
    42             // create a new bucket
    43             array[index] = [(key,value)]
    44         }
    45     }
    46     
    47     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    48     func get(_ key: Int) -> Int {
    49         let index = getIndex(key)
    50         let pos = getPos(key, index)
    51         if array[index] != nil && pos >= 0 {
    52             return array[index]![pos].value
    53         } 
    54         return -1
    55     }
    56     
    57     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    58     func remove(_ key: Int) {
    59         let index = getIndex(key)
    60         let pos = getPos(key, index) 
    61         if array[index] != nil && pos >= 0 {
    62             array[index]!.remove(at: pos)
    63         }
    64     }
    65 }

    572ms

      1 class ListNode<T> {
      2     var value: T
      3     var next: ListNode<T>?
      4     
      5     init(value: T) {
      6         self.value = value
      7     }
      8 }
      9 
     10 class HashMap<Key: Hashable, Value> {
     11     
     12     private struct Pair {
     13         var key: Key
     14         var value: Value
     15     }
     16     
     17     private var buckets = [ListNode<Pair>?](repeating: nil, count: 1000)
     18 
     19     func put(key: Key, value: Value) {
     20         
     21         let pair = Pair(key: key, value: value)
     22         
     23         if let existingNodes = find(key: key) {
     24             existingNodes.node.value = pair
     25         } else {
     26             
     27             let index = hash(from: key) % buckets.count
     28             
     29             let newNode = ListNode<Pair>(value: pair)
     30             newNode.next = buckets[index]
     31             buckets[index] = newNode
     32         }
     33     }
     34     
     35     func get(key: Key) -> Value? {
     36         return find(key: key)?.node.value.value
     37     }
     38     
     39     func remove(key: Key) {
     40         guard let nodes = find(key: key) else {
     41             return // couldn't find it
     42         }
     43         
     44         if let previousNode = nodes.previousNode {
     45             previousNode.next = nodes.node.next
     46         } else {
     47             let index = hash(from: key) % buckets.count
     48             buckets[index] = nodes.node.next
     49         }
     50     }
     51     
     52     private func find(key: Key) -> (previousNode: ListNode<Pair>?, node: ListNode<Pair>)? {
     53         let hashValue = hash(from: key)
     54         let index = hashValue % buckets.count
     55         
     56         var previousNode: ListNode<Pair>? = nil
     57         var currentNode: ListNode<Pair>? = buckets[index]
     58         
     59         while let _currentNode = currentNode {
     60             if _currentNode.value.key == key {
     61                 return (previousNode, _currentNode)
     62             }
     63             
     64             previousNode = _currentNode
     65             currentNode = _currentNode.next
     66         }
     67         
     68         return nil
     69     }
     70     
     71     private func hash(from key: Key) -> Int {
     72         return abs(key.hashValue)
     73     }
     74 }
     75 
     76 
     77 class MyHashMap {
     78     
     79     private let hashMap = HashMap<Int, Int>()
     80 
     81     /** Initialize your data structure here. */
     82     init() {
     83         
     84     }
     85     
     86     /** value will always be non-negative. */
     87     func put(_ key: Int, _ value: Int) {
     88         hashMap.put(key: key, value: value)
     89     }
     90     
     91     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
     92     func get(_ key: Int) -> Int {
     93         guard let value = hashMap.get(key: key) else {
     94             return -1
     95         }
     96         return value
     97     }
     98     
     99     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    100     func remove(_ key: Int) {
    101         hashMap.remove(key: key)
    102     }
    103 }

    596ms

      1 struct Pair {
      2     let key: Int
      3     let value: Int
      4 }
      5 
      6 class ListNode<T> {
      7     
      8     var value: T
      9     
     10     var next: ListNode<T>?
     11     
     12     init(value: T) {
     13         self.value = value
     14     }
     15 }
     16 
     17 class MyHashMap {
     18     
     19     private static let bucketLength = 10_000
     20     
     21     private var buckets = [ListNode<Pair>?](repeating: nil, count: MyHashMap.bucketLength)
     22 
     23     /** Initialize your data structure here. */
     24     init() {
     25         
     26     }
     27     
     28     /** value will always be non-negative. */
     29     func put(_ key: Int, _ value: Int) {
     30         
     31         let pair = Pair(key: key, value: value)
     32         
     33         if let nodes = find(key: key) {
     34             nodes.node.value = pair // override the current
     35         } else {
     36             let hash = hashFromKey(key)
     37             let index = hash % buckets.count
     38             
     39             let newNode = ListNode<Pair>(value: pair)
     40             newNode.next = buckets[index]
     41             buckets[index] = newNode
     42         }
     43     }
     44     
     45     /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
     46     func get(_ key: Int) -> Int {
     47         guard let nodes = find(key: key) else {
     48           return -1
     49         }
     50         return nodes.node.value.value
     51     }
     52     
     53     /** Removes the mapping of the specified value key if this map contains a mapping for the key */
     54     func remove(_ key: Int) {
     55         guard let nodes = find(key: key) else {
     56             return // not node found for the key
     57         }
     58         
     59         let node = nodes.node
     60         
     61         if let previous = nodes.previous {
     62             previous.next = node.next
     63         } else {
     64             // its the head
     65             let hash = hashFromKey(key)
     66             let index = hash % buckets.count 
     67             buckets[index] = node.next
     68         }
     69     }
     70     
     71     private func hashFromKey(_ x: Int) -> Int {
     72         // var x = x
     73         // x = ((x >> 16) ^ x) * 0x45d9f3b;
     74         // x = ((x >> 16) ^ x) * 0x45d9f3b;
     75         // x = (x >> 16) ^ x;
     76         return x*2654435761
     77         
     78 //         if key & 1 == 1 { // odd
     79 //             return (key + 1_000_000)
     80 //         } else {
     81 //             return key * 7
     82 //         }
     83     }
     84     
     85     private func find(key: Int) -> (previous: ListNode<Pair>?, node: ListNode<Pair>)? {
     86         
     87         let hash = hashFromKey(key)
     88         let index = hash % buckets.count
     89         
     90         var previousNode: ListNode<Pair>? = nil
     91         var currentNode = buckets[index]
     92         while let _currentNode = currentNode {
     93             if _currentNode.value.key == key {
     94                 return (previousNode, _currentNode)
     95             } 
     96             
     97             previousNode = _currentNode
     98             currentNode = _currentNode.next // keep searching
     99         }        
    100         
    101         return nil // did not find
    102     }
    103 }
  • 相关阅读:
    Createjs学习心得之使用EaselJs实现拖拽效果
    学习笔记——复杂的窗口分帧
    cordova 插件开发
    wcf rest 服务用于安卓和ISO调用5-------验证
    wcf rest 服务用于安卓和ISO调用4-------多文件上传
    wcf rest 服务用于安卓和ISO调用3-------soap与rest共用
    wcf rest 服务用于安卓和ISO调用2-------文件上传
    wcf rest 服务用于安卓和ISO调用1
    RecycleView 瀑布流滑动移位
    RecycleView 滑动到底部,加载更多
  • 原文地址:https://www.cnblogs.com/strengthen/p/10506126.html
Copyright © 2011-2022 走看看