contents

๐Ÿ”‘ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ํ•ด์‹ฑ(Hashing) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ€์ด๋“œ & ์˜ˆ์ œ

ํ•ด์‹ฑ์€ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ๋‚˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ ํ’€์ด์—์„œ ๋งค์šฐ ์ค‘์š”ํ•œ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค.
"๋น ๋ฅธ ์กฐํšŒ", "์ค‘๋ณต ์ œ๊ฑฐ", "๋นˆ๋„ ๊ณ„์‚ฐ"๊ณผ ๊ฐ™์€ ๋ฌธ์ œ ํ’€์ด ํŠธ๋ฆญ์˜ ํ•ต์‹ฌ์— ์žˆ์Šต๋‹ˆ๋‹ค.


1. ํ•ด์‹ฑ(Hashing) ์ด๋ž€?

ํ•ด์‹ฑ์€ ์ •์ˆ˜, ๋ฌธ์ž์—ด ๋“ฑ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ **ํ•ด์‹œ ํ•จ์ˆ˜(Hash Function)**๋ฅผ ์ด์šฉํ•ด ๊ณ ์ • ํฌ๊ธฐ์˜ ํ•ด์‹œ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ, ๋น ๋ฅธ ๊ฒ€์ƒ‰/์ €์žฅ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.


2. ์ฃผ์š” ํ•ด์‹œ ์ž๋ฃŒ๊ตฌ์กฐ

a. HashMap / HashSet (Java), Dictionary (Python)

Java ์˜ˆ์‹œ โ€“ ์ˆซ์ž ๋นˆ๋„ ์นด์šดํŠธ

int[] arr = {3, 5, 4, 3, 4, 3};
Map<Integer, Integer> map = new HashMap<>();
for (int num : arr)
    map.put(num, map.getOrDefault(num, 0) + 1);

if (map.containsKey(5)) { /* ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ */ }

Java ์˜ˆ์‹œ โ€“ ์กด์žฌ ์—ฌ๋ถ€๋งŒ ์ฒดํฌ

Set<Integer> set = new HashSet<>();
for (int num : arr) set.add(num);

boolean isPresent = set.contains(4);

b. ๋ฌธ์ž์—ด์˜ ๋นˆ๋„ ์นด์šดํŠธ

String s = "programming";
Map<Character, Integer> freq = new HashMap<>();
for (char c : s.toCharArray())
    freq.put(c, freq.getOrDefault(c, 0) + 1);

๐Ÿ‘‰ ์•„๋‚˜๊ทธ๋žจ ๊ฒ€์ฆ, ์ค‘๋ณต ํƒ์ง€, ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๋“ฑ์— ํ™œ์šฉ


3. ํ•ด์‹ฑ ์‘์šฉ ์˜ˆ์‹œ

a. ์ค‘๋ณต ํƒ์ง€

Set<Integer> seen = new HashSet<>();
for (int num : arr) {
    if (seen.contains(num)) { /* ์ค‘๋ณต ๋ฐœ๊ฒฌ */ }
    seen.add(num);
}

b. Two Sum ๋ฌธ์ œ

Map<Integer, Integer> map = new HashMap<>();
for (int num : arr) {
    if (map.containsKey(target - num)) {
        // num๊ณผ target - num์ด ํ•œ ์Œ
    }
    map.put(num, 1);
}

c. ๋ถ€๋ถ„ํ•ฉ = K ๋ฌธ์ œ


4. ํ•ด์‹œ ํ•จ์ˆ˜ ์„ค๊ณ„ ํŒ

์ง์ ‘ ๊ตฌํ˜„ ์‹œ:

int hash(String s) {
    int hash = 0, p = 31, M = 1_000_000_007;
    for (int i = 0; i < s.length(); i++)
        hash = (hash + s.charAt(i) * pow(p, i)) % M;
    return hash;
}

โš ๏ธ ๋ณดํ†ต Java/Python์˜ ๋‚ด์žฅ HashMap/HashSet์€ ์ด๋ฏธ ์•ˆ์ „ํ•œ ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ


5. ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ์—์„œ ํ•ด์‹ฑ์ด ์ž์ฃผ ์“ฐ์ด๋Š” ํŒจํ„ด

ํŒจํ„ด ํ™œ์šฉ ์‚ฌ๋ก€ ์˜ˆ์‹œ
๋น ๋ฅธ ์กด์žฌ ์—ฌ๋ถ€ ๊ฐ’์ด ์กด์žฌํ•˜๋Š”์ง€ O(1)๋กœ ํ™•์ธ HashSet.contains(val)
๋นˆ๋„ ์นด์šดํŒ… K-๋นˆ๋„, ์•„๋‚˜๊ทธ๋žจ, ๋งค์นญ ๋ฌธ์ œ map.getOrDefault(key, 0)
์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด ๊ณ ์œ ์„ฑ, ์•„๋‚˜๊ทธ๋žจ ์ฐพ๊ธฐ HashSet ๋˜๋Š” Rolling Hash
๋ฉ”๋ชจ์ด์ œ์ด์…˜(DP) ์ƒํƒœ๋ณ„ ๊ฒฐ๊ณผ ์บ์‹œ Map<State, Result>
๋ณตํ•ฉ ํ‚ค (a,b) ๋˜๋Š” ๋ฐฐ์—ด์„ Key๋กœ ์‚ฌ์šฉ Map<List, Value> / Map<Tuple, Value>
O(n) ์ตœ์ ํ™” ํŠธ๋ฆญ ์ค‘์ฒฉ ๋ฃจํ”„ ํ”ผํ•˜๊ธฐ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํ•ด์‹œ๋กœ ์ฒดํฌ

6. ์ถฉ๋Œ(Collision) ์ฒ˜๋ฆฌ ๋ฐฉ์‹

Java, Python์˜ ํ‘œ์ค€ ํ•ด์‹œ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์ด๋Ÿฐ ๊ณผ์ •์„ ์ž๋™ ์ฒ˜๋ฆฌ


7. ์‹ค์ˆ˜/์ฃผ์˜์‚ฌํ•ญ & ํŒ


8. ๋Œ€ํ‘œ ํ•ด์‹œ ํ™œ์šฉ ๋ฌธ์ œ (์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๋นˆ์ถœ)


9. ์ •๋ฆฌ ํ‘œ

๋ฌธ์ œ ์œ ํ˜• ํ•ด์‹œ ํ™œ์šฉ ์ž์ฃผ ์“ฐ๋Š” ์ฝ”๋“œ ์˜ˆ์‹œ
์ค‘๋ณต ์ฒดํฌ HashSet if set.contains(val) ...
๋น ๋ฅธ ์กฐํšŒ/๋นˆ๋„ ๊ณ„์‚ฐ HashMap/Dictionary map.getOrDefault(key, 0)
์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ HashSet set.add(substring)
์•„๋‚˜๊ทธ๋žจ/๊ทธ๋ฃนํ™” Map<sorted String, List> map.put(sort(s), list)
DP ๋ฉ”๋ชจ์ด์ œ์ด์…˜ Map<State, Result> memo.put(state, result)

๐Ÿ’ก Tip:
๋Œ€ํ‘œ ํ•ด์‹œ ํŒจํ„ด(์ค‘๋ณต ์ฒดํฌ, ๋นˆ๋„์ˆ˜ ๊ณ„์‚ฐ, Two Sum, ๋ถ€๋ถ„ํ•ฉ, ์•„๋‚˜๊ทธ๋žจ)์„ ๋ฐ˜๋“œ์‹œ ์†์ฝ”๋”ฉ์œผ๋กœ ์—ฐ์Šตํ•˜์„ธ์š”.
Python dict/set, Java HashMap/HashSet API ์‚ฌ์šฉ๋ฒ•๋„ ์ต์ˆ™ํ•ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ—๏ธ ํ•ด์‹œ ํ…Œ์ด๋ธ” ์ถฉ๋Œ ์ฒ˜๋ฆฌ(Collision Handling) โ€“ ์‹ฌ์ธต ๊ฐ€์ด๋“œ & ์ฃผ์š” ๊ธฐ๋ฒ•

ํ•ด์‹œ ํ…Œ์ด๋ธ”์—์„œ๋Š” ์ถฉ๋Œ(Collision) โ€” ์„œ๋กœ ๋‹ค๋ฅธ ํ‚ค๊ฐ€ ๋™์ผํ•œ ์ธ๋ฑ์Šค์— ๋งคํ•‘๋˜๋Š” ์ƒํ™ฉ โ€” ์ด ํ•„์—ฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๊ฒฌ๊ณ ํ•œ ์ถฉ๋Œ ์ฒ˜๋ฆฌ๋Š” ํ…Œ์ด๋ธ”์ด ๊ฐ€๋“ ์ฐจ๋”๋ผ๋„, ๋˜๋Š” ํ•ด์‹œ ํ•จ์ˆ˜๊ฐ€ ์™„๋ฒฝํ•˜์ง€ ์•Š๋”๋ผ๋„, ๋น ๋ฅธ ์ €์žฅ/์กฐํšŒ/์‚ญ์ œ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.
์•„๋ž˜๋Š” ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๊ด€์ ์—์„œ ์ถฉ๋Œ ์ฒ˜๋ฆฌ ๊ธฐ๋ฒ•, ์›๋ฆฌ, ์žฅ๋‹จ์ ์„ ์ƒ์„ธํžˆ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.


1. ๋ถ„๋ฆฌ ์ฒด์ด๋‹(Separate Chaining)

์˜ˆ: ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ N์ด๊ณ , ํ•ด์‹œ๊ฐ€ key % size๋ผ๋ฉด, 7๊ณผ 14๋Š” ๋™์ผํ•œ ํ•ด์‹œ ์Šฌ๋กฏ 0์œผ๋กœ ์ด๋™.
์Šฌ๋กฏ 0์—๋Š” ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ [7 โ†’ 14] ์ €์žฅ.


2. ์˜คํ”ˆ ์–ด๋“œ๋ ˆ์‹ฑ(Open Addressing)

๋ชจ๋“  ํ‚ค๋ฅผ ํ…Œ์ด๋ธ” ๋ฐฐ์—ด ์•ˆ์— ์ง์ ‘ ์ €์žฅํ•˜๋ฉฐ, ์ถฉ๋Œ ์‹œ ์ผ์ •ํ•œ ๊ทœ์น™(ํ”„๋กœ๋น™ ์ˆœ์„œ)์— ๋”ฐ๋ผ ๋‹ค์Œ ๋นˆ ์Šฌ๋กฏ์„ ํƒ์ƒ‰ํ•ด ์‚ฝ์ž….

์ข…๋ฅ˜:

a. ์„ ํ˜• ํƒ์‚ฌ(Linear Probing)

b. ์ด์ฐจ ํƒ์‚ฌ(Quadratic Probing)

c. ์ด์ค‘ ํ•ด์‹ฑ(Double Hashing)

์˜คํ”ˆ ์–ด๋“œ๋ ˆ์‹ฑ ํŠน์ง•:


3. ๊ธฐํƒ€ ์ถฉ๋Œ ์ฒ˜๋ฆฌ ๊ธฐ๋ฒ•

๋กœ๋นˆ ํ›„๋“œ ํ•ด์‹ฑ(Robin Hood Hashing)

์ฟ ์ฟ  ํ•ด์‹ฑ(Cuckoo Hashing)

ํ™‰์Šค์ฝง์น˜ ํ•ด์‹ฑ(Hopscotch Hashing)


4. ๋น„๊ต ํ‘œ & ํŒ

๋ฐฉ๋ฒ• ์กฐํšŒ ์†๋„ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ ์‚ญ์ œ ํŽธ์˜ ๊ตฐ์ง‘ํ™” ์œ„ํ—˜
๋ถ„๋ฆฌ ์ฒด์ด๋‹ ์ข‹์Œ ๋†’์Œ(๋ฆฌ์ŠคํŠธ) ์‰ฌ์›€ ๋‚ฎ์Œ
์„ ํ˜• ํƒ์‚ฌ ๋งค์šฐ ์ข‹์Œ ๋‚ฎ์Œ ์–ด๋ ค์›€ ๋†’์Œ(1์ฐจ ๊ตฐ์ง‘ํ™”)
์ด์ฐจ ํƒ์‚ฌ ์ข‹์Œ ๋‚ฎ์Œ ์–ด๋ ค์›€ ๋ณดํ†ต(2์ฐจ ๊ตฐ์ง‘ํ™”)
์ด์ค‘ ํ•ด์‹ฑ ๋งค์šฐ ์ข‹์Œ ๋‚ฎ์Œ ์–ด๋ ค์›€ ๋‚ฎ์Œ
์ฟ ์ฟ /ํ™‰์Šค์ฝง์น˜ ๋งค์šฐ ์ข‹์Œ ๋ณดํ†ต ๋ณต์žกํ•จ ๋งค์šฐ ๋‚ฎ์Œ

5. Java/Python์—์„œ์˜ ์ถฉ๋Œ ์ฒ˜๋ฆฌ


โœ… ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ํŒ:
์ง์ ‘ ํ•ด์‹œ ํ…Œ์ด๋ธ” ๊ตฌํ˜„ ๋ฌธ์ œ๊ฐ€ ๋‚˜์˜ค๋ฉด, ๋ถ„๋ฆฌ ์ฒด์ด๋‹๊ณผ ์˜คํ”ˆ ์–ด๋“œ๋ ˆ์‹ฑ(์„ ํ˜• ํƒ์‚ฌ) ๋‘ ๊ฐ€์ง€๋Š” ์†์ฝ”๋”ฉ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

references