HashMap์ Map์ ๊ตฌํํ ํด๋์ค์ด๊ธฐ ๋๋ฌธ์, <key, value> ํํ๋ก ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ๋ค. ํญ์ ์ฃผ์ด์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉ๋ง ํ๊ธฐ ๋๋ฌธ์, ์ด๋ป๊ฒ ๊ตฌํ๋์ด ์๋์ง์ ๋ํด์๋ ๊ณ ๋ฏผํด๋ณด์ง ์์๋๋ฐ ๋๋ถ์ bucket์ด๋ผ๋ ๊ฐ๋ ๋ ์๊ฒ ๋์๋ค.
์ด๋ฒ ๋ฌธ์ ๋ ๊ณต๋ถํ๋ ์ฐจ์์์ ํผ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๋ฐ๋ก ํ์ด๋ค์ ์ข ์ฐพ์ ๋ณด์๋ค.
์ฒซ ๋ฒ์งธ Solution
์ด์ฐจํผ key์ ๋ฒ์๊ฐ 0๋ถํฐ 1,000,000, ์ฆ ๋ฐฑ๋ง์ด๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด์ ์์ฑํด์ ๊ตฌํํด๋ ๋ฌธ์ ๊ฐ ์๋ค.
MyHashMap ํด๋์ค ์์ฑ ์์, ํฌ๊ธฐ 1000001์ธ ๋ฐฐ์ด์ ์ ์ธํ ๋ค์์ index๋ฅผ ํค๊ฐ์ฒ๋ผ ์๊ฐํด์ ๊ตฌํํ๋ฉด ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(1) (
get
,remove
,put
๋ชจ๋์ ํด๋น๋๋ค) - ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
class MyHashMap {
int[] map;
/** Initialize your data structure here. */
public MyHashMap() {
map = new int[1000001];
Arrays.fill(map, -1);
}
/** value will always be non-negative. */
public void put(int key, int value) {
map[key+1] = value;
}
/** Returns the value to which the specified key is mapped,
or -1 if this map contains no mapping for the key */
public int get(int key) {
return map[key+1];
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
map[key+1] = -1;
}
}
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
๋ ๋ฒ์งธ Solution
์กฐ๊ธ ๋ ๋ณต์กํ๋ค. Bucket์ ๊ฐ๋ ์ ์ด์ฉํ๋๋ฐ, Bucket์ ๊ตฌํํ๊ธฐ ์ํด์๋ LinkedList๋ฅผ ์ฌ์ฉํ๋ค.
์ด ํ์ด๋ฒ์ ์๋ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ์กฐํ๋ค. ์ ๋ง ์ ์ค๋ช ํด๋์๋ค!
developer-hongjoo.tistory.com/33?category=815694
์ฝ์ผ๋ฉด์ ์ค์ HashMap ๊ตฌํ ๋ก์ง๊ณผ ํท๊ฐ๋ฆฌ์ง ์๋๋ก ์ ์ํด์ผ ํ ๋ถ๋ถ์ด ์๋ค๊ณ ์๊ฐํ๋ค.
ํ์ฌ ๋ก์ง์์๋ key๊ฐ์ด ์์นํ bucket์ index๋ฅผ ๊ฒฐ์ ์ง๊ธฐ ์ํด ์์๋ก key๋ฅผ BUCKET_CAPACITY
๋ก ๋๋์๋ค. ์ด์ฒ๋ผ ํ๋ฉด BUCKET_CAPACITY
์ ๋ฐ๋ผ ์๊ฐ ๋ณต์ก๋๊ฐ ๋ฌ๋ผ์ง ๊ฒ ๊ฐ์๋ฐ, ์ค์ Hash Function์ด ์ด๋ป๊ฒ ๊ตฌ์ฑ๋๋ ์ง๋ ๊ถ๊ธํ๋ค.
โป ๋ง์ฝ BUCKET_CAPACITY
= 2๋ผ๋ฉด, bucket
๋ฐฐ์ด ํ๋์ ์ต๋ 2๊ฐ์ node๋ง ๋ค์ด๊ฐ ์ ์๊ธฐ ๋๋ฌธ์, ์ฑ๋ฅ์ด ์ข์์ง ์ ๋ฐ์ ์๋ค.
index | key |
0 | 0~99 |
1 | 100~199 |
~ | ~ |
9,999 | 999,900~999,999 |
10,000 | 1,000,000 |
๋ ๊ฐ์ง ๋ด๊ฐ ์์ ํ ๋ถ๋ถ์ด ์๋ค.
์ฒซ ๋ฒ์งธ๋ก, remove()
์์ bucket[index]
์ ๋ฌ๋ฆฐ ๋
ธ๋๊ฐ ๋ฑ 1๊ฐ์์ ๋์๋ bucket[index]
์์ฒด๋ฅผ null
๋ก ์ด๊ธฐํํ์ฌ์(line #89) put
ํ ๋์ ์๋ฌด ๋ฌธ์ ์์ด new Bucket
์ผ๋ก ๊ฐ์ ์ง์ด๋ฃ์ ์ ์๋๋ก ํ๋ค.
๋ ๋ฒ์งธ๋ก, bucket
๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ 10001๋ก ๋๋ ธ๋ค. ๋ค์ด์ฌ ์ ์๋ ๊ฐ์ ๋ฒ์๊ฐ [0,1000000]๋ฉด 1000000์ด key๋ก ๋ค์ด์์ ๋์๋ index๊ฐ 10000์ด์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ฌ ๋ก์ง์์์๋ ์๊ฐ ๋ณต์ก๋์ ๊ณต๊ฐ ๋ณต์ก๋๊ฐ trade-off ๊ด๊ณ์ ์๊ณ , BUCKET_CAPACITY
์ ๋ฐ๋ผ ์๊ฐ ๋ณต์ก๋๊ฐ ํฌ๊ฒ ๋ฐ๋ ๊ฒ ๊ฐ๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(BUCKET_CAPACITY)
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n/BUCKET_CAPACITY) ← ์ฌ๊ธฐ์์์ n์ key๋ก ๋ค์ด์ฌ ์ ์๋ ์ต๋๊ฐ
class MyHashMap {
static final int BUCKET_CAPACITY = 100;
static Bucket[] buckets;
class Bucket{
Node node;
public Bucket(Node node){
this.node = node;
}
}
class Node{
int key;
int value;
Node next;
public Node(int key, int value, Node next){
this.key = key;
this.value = value;
this.next = next;
}
}
/** Initialize your data structure here. */
public MyHashMap() {
buckets = new Bucket[10001];
}
/** value will always be non-negative. */
public void put(int key, int value) {
int index = key/BUCKET_CAPACITY;
if(buckets[index] == null){
buckets[index] = new Bucket(new Node(key,value,null));
}else{
Node node = buckets[index].node;
while(node!=null){
if(node.key==key){
node.value = value;
return;
}
if(node.next==null){
node.next = new Node(key,value,null);
return;
}
node = node.next;
}
}
}
/** Returns the value to which the specified key is mapped,
or -1 if this map contains no mapping for the key */
public int get(int key) {
int index = key/BUCKET_CAPACITY;
if(buckets[index]==null){
return -1;
}else{
Node node = buckets[index].node;
while(node!=null){
if(node.key==key) return node.value;
node = node.next;
}
return -1;
}
}
/** Removes the mapping of the specified value key
if this map contains a mapping for the key */
public void remove(int key) {
int index = key/BUCKET_CAPACITY;
if(buckets[index]==null) return;
else{
Node node = buckets[index].node;
Node prev = null;
while(node!=null){
if(node.key==key){
if(prev==null){ //๋ฑ ์ฒซ๋ฒ์งธ ๋
ธ๋๊ฐ removeํ๋ ค๋ ๊ฐ์ผ๋
//Bucket์ node๊ฐ ๋ฑ 1๊ฐ์์ ๋๋,
//Bucket ์์ฒด๋ clear ์์ผ์ค๋ค.
buckets[index].node = node.next;
if(node.next==null) buckets[index] = null;
return;
}else{
prev.next = node.next;
return;
}
}else{
prev = node;
node = node.next;
}
}
}
}
}
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
'์๊ณ ๋ฆฌ์ฆ > ๋ฌธ์ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฐ] Leetcode 1302 - Deepest Leaves Sum (0) | 2021.04.11 |
---|---|
[์๋ฐ] Leetcode 1332 - Remove Palindromic Subsequences (0) | 2021.03.09 |
[์๋ฐ] Leetcode 637 - Average of Levels in Binary Tree (0) | 2021.03.05 |
[์๋ฐ] Leetcode 268 - Missing Number (0) | 2021.03.04 |
[์๋ฐ] Leetcode 234 - Palindrome Linked List (0) | 2021.03.01 |