为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode706. 设计哈希映射 | Design HashMap

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

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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 }

 

posted @ 2019-03-10 17:41  为敢技术  阅读(818)  评论(2编辑  收藏  举报