forked from super30admin/Design-2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHashMap.js
More file actions
275 lines (250 loc) · 8.23 KB
/
Copy pathHashMap.js
File metadata and controls
275 lines (250 loc) · 8.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// Time Complexity : O(1)
// Space Complexity : O(n)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No
/*
* Approach - Double Hashing
* Since the constraint was 0 - 10^6 we use the sqrt to split buckets to avoid huge memory wastage
* We use double hashing to avoid collision
* PUT:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we initialize it to a 2D
* array with the bucketItems length and defaulting it to -1.
* - if it's not then we do storage[bucket][bucketItem] and set the value to true
*
* Remove:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we return null
* - if it's not then we do storage[bucket][bucketItem] = -1 since we are removing the value
*
* GET:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we return -1
* - if it's not then we return storage[bucket][bucketItem]
* which would be value / -1 depending on if the value exists
*
* */
// Time Complexity : O(1)
// Space Complexity : O(n)
// Did this code successfully run on Leetcode : Yes
// Any problem you faced while coding this : No
/*
* Approach - Double Hashing
* Since the constraint was 0 - 10^6 we use the sqrt to split buckets to avoid huge memory wastage
* We use double hashing to avoid collision
* PUT:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we initialize it to a 2D
* array with the bucketItems length and defaulting it to -1.
* - if it's not then we do storage[bucket][bucketItem] and set the value to true
*
* Remove:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we return null
* - if it's not then we do storage[bucket][bucketItem] = -1 since we are removing the value
*
* GET:
* - We get the first hash value by using key % buckets
* - We get the second hash value by key / bucketItems
* - if the array of the fist hash is empty or null we return -1
* - if it's not then we return storage[bucket][bucketItem]
* which would be valye / -1 depending on if the value exists
*
* */
// const MyHashMap = function() {
// this.buckets = 1000;
// this.bucketItems = 1000;
// this.storage = new Array(this.buckets).fill(null);
// };
// /**
// * @param {number} key
// * @return {number}
// */
// MyHashMap.prototype.getBuckets = function (key) {
// return key % this.buckets;
// }
// /**
// * @param {number} key
// * @return {number}
// */
// MyHashMap.prototype.getBucketItems = function (key) {
// return Math.floor(key / this.bucketItems);
// }
// /**
// * @param {number} key
// * @param {number} value
// * @return {void}
// */
// MyHashMap.prototype.put = function(key, value) {
// const bucket = this.getBuckets(key);
// const bucketItem = this.getBucketItems(key);
// if (this.storage[bucket] === null) {
// this.storage[bucket] = new Array(this.bucketItems).fill(-1)
// }
// this.storage[bucket][bucketItem] = value;
// };
// /**
// * @param {number} key
// * @return {number}
// */
// MyHashMap.prototype.get = function(key) {
// const bucket = this.getBuckets(key);
// const bucketItem = this.getBucketItems(key);
// if (this.storage[bucket] === null) {
// return -1;
// }
// return this.storage[bucket][bucketItem]
// };
// /**
// * @param {number} key
// * @return {void}
// */
// MyHashMap.prototype.remove = function(key) {
// const bucket = this.getBuckets(key);
// const bucketItem = this.getBucketItems(key);
// if (this.storage[bucket] === null) {
// return;
// }
// this.storage[bucket][bucketItem] = -1;
// };
/**
* Your MyHashMap object will be instantiated and called as such:
* var obj = new MyHashMap()
* obj.put(key)
* obj.remove(key)
* var param_3 = obj.get(key)
*/
// var obj = new MyHashMap()
// console.log(obj.remove(2))
// obj.put(3,11)
// obj.put(4,13)
// obj.put(15,6)
// obj.put(6,15)
// obj.put(8,8)
// obj.put(11,0)
// obj.get(11);
// console.log(obj.storage[11])
// Time Complexity : O(N) - To find the node
// Space Complexity : O(n)
/*Approach - Single Hashing with Linked list
* Similar approach as double hashing but instead of we use a single hash as the primary array
* for the secondary array we use a linked list to store the list of items.
*
* Note: % is mostly used so that the values dont cross the upper bound
* Put:
* - To perform put we first have to get the bucket but the first hashing (%)
* - The we have the find if the node exists in the storage,
* - if it doesn't then we create a linked list with the dummy node elements fist.
* - the dummy node is used a reference to the head in case we have to delete the first element/
* - if the element is found using findNode then we check if the next value is null
* - if it is we add prev.next = new Node(value, key)
* else which means that the next element is the key then we do prev.next.value = value
* Find:
* - It has dummyNode and the key as the arguemtns
* - we assign dummy node to prev and curr to the dummyNodes.next
* - if the curr is null or the curr.key is the key then we return the prev
* else we loop till the condition breaks and return prev
*
* Remove
* - To perform put we first have to get the bucket but the first hashing (%)
* - The we have the find if the node exists in the storage,
* - if it doesn't then we create a linked list with the dummy node elements fist.
* - the dummy node is used a reference to the head in case we have to delete the first element/
* - if the element is found using findNode then we check if the next value is null
* - if the prev.next is null then we return
* else we do prev.next = prev.next.next to remove
*
* Get
* - To perform put we first have to get the bucket but the first hashing (%)
* - The we have the find if the node exists in the storage,
* - if it doesn't then we create a linked list with the dummy node elements fist.
* - the dummy node is used a reference to the head in case we have to delete the first element/
* - if the element is found using findNode then we check if the next value is null
* - if prev.next is null then we return -1
* - else we return the value at prev.next
* */
class Node {
constructor(data, key) {
this.val = data;
this.key = key;
this.next = null
}
}
const MyHashMap = function() {
this.buckets = 10000;
this.bucketItems = 100;
this.storage = new Array(this.buckets).fill(null);
};
/**
* @param {number} key
* @return {number}
*/
MyHashMap.prototype.getBuckets = function (key) {
return key % this.buckets;
}
MyHashMap.prototype.findNode = function (dummyNode, key) {
let prev = dummyNode;
let curr = dummyNode.next;
while (curr && curr.key !== key) {
prev = curr;
curr = curr.next;
}
return prev;
}
/**
* @param {number} key
* @return {number}
*/
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
MyHashMap.prototype.put = function(key, value) {
const bucket = this.getBuckets(key);
if (!this.storage[bucket]) {
this.storage[bucket] = new Node(-1, key);
}
let prev = this.findNode(this.storage[bucket], key);
if (prev.next == null) {
prev.next = new Node(value, key)
} else {
prev.next.val = value;
}
};
/**
* @param {number} key
* @return {number}
*/
MyHashMap.prototype.get = function(key) {
const bucket = this.getBuckets(key);
if (!this.storage[bucket]) {
return -1
}
let prev = this.findNode(this.storage[bucket], key);
if (!prev.next) {
return -1;
}
return prev.next.val;
};
/**
* @param {number} key
* @return {void}
*/
MyHashMap.prototype.remove = function(key) {
const bucket = this.getBuckets(key);
if (!this.storage[bucket]) {
return;
}
let prev = this.findNode(this.storage[bucket], key);
if (!prev.next) {
return;
} else {
prev.next = prev.next.next;
}
};