[Swift]LeetCode706. 設計哈希映射 | Design HashMap

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-zxejixjd-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

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

To be specific, your design should include these functions:git

  • 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:github

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.

不使用任何內建的哈希表庫設計一個哈希映射app

具體地說,你的設計應該包含如下的功能ide

  • put(key, value):向哈希映射中插入(鍵,值)的數值對。若是鍵對應的值已經存在,更新這個值。
  • get(key):返回給定的鍵所對應的值,若是映射中不包含這個鍵,返回-1。
  • remove(key):若是映射中存在這個鍵,刪除這個數值對。

示例:ui

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 (未找到)

注意:this

    • 全部的值都在 [1, 1000000]的範圍內。
    • 操做的總數目在[1, 10000]範圍內。
    • 不要使用內建的哈希庫。

 484msspa

 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 }
相關文章
相關標籤/搜索