[Python-알고리즘] 해시테이블

2025. 5. 26. 17:11·개발이야기/파이썬
728x90
해시테이블 (Hash Table) 정리 및 자주 쓰이는 응용문제

해시테이블 (Hash Table) 정리 및 자주 쓰이는 응용문제

1. 해시테이블이란?

해시테이블은 키(Key)를 해시 함수(Hash Function)를 통해 해시값으로 변환하여, 데이터(값, Value)를 빠르게 저장하고 조회하는 자료구조입니다.
평균적으로 O(1)의 시간 복잡도로 삽입, 삭제, 탐색이 가능해 매우 효율적입니다.
하지만, 서로 다른 키들이 같은 해시값을 가질 수 있는데, 이를 충돌(Collision)이라고 합니다.

2. 충돌 해결 방법 (Collision Resolution)

2-1. 체이닝 (Separate Chaining)

충돌이 발생한 인덱스에 연결 리스트(또는 다른 자료구조)를 두어, 충돌한 데이터를 모두 저장하는 방식입니다.

  • 구현이 간단하며, 충돌이 많아도 성능 저하가 완화됨
  • 메모리를 동적으로 사용할 수 있어 확장성이 좋음
# 파이썬 예시: 리스트를 이용한 체이닝
class HashTableChaining:
    def __init__(self, size=10):
        self.size = size
        self.table = [[] for _ in range(size)]

    def _hash(self, key):
        return hash(key) % self.size

    def set(self, key, value):
        index = self._hash(key)
        for i, (k, v) in enumerate(self.table[index]):
            if k == key:
                self.table[index][i] = (key, value)
                return
        self.table[index].append((key, value))

    def get(self, key):
        index = self._hash(key)
        for k, v in self.table[index]:
            if k == key:
                return v
        return None

2-2. 오픈 어드레싱 (Open Addressing)

충돌이 발생하면 해시 테이블 내에서 다른 빈 공간을 찾아 데이터를 저장하는 방식입니다.

  • 선형 탐사(Linear Probing), 이차 탐사(Quadratic Probing), 이중 해싱(Double Hashing) 등의 기법이 있음
  • 테이블이 꽉 차면 성능이 급격히 떨어지므로 적절한 크기 조절이 필요
# 파이썬 예시: 선형 탐사 방식 (Open Addressing - Linear Probing)
class HashTableOpenAddressing:
    def __init__(self, size=10):
        self.size = size
        self.keys = [None] * size
        self.values = [None] * size

    def _hash(self, key):
        return hash(key) % self.size

    def set(self, key, value):
        index = self._hash(key)
        start_index = index

        while self.keys[index] is not None and self.keys[index] != key:
            index = (index + 1) % self.size
            if index == start_index:
                raise Exception("Hash table is full")

        self.keys[index] = key
        self.values[index] = value

    def get(self, key):
        index = self._hash(key)
        start_index = index

        while self.keys[index] is not None:
            if self.keys[index] == key:
                return self.values[index]
            index = (index + 1) % self.size
            if index == start_index:
                break
        return None

3. 해시테이블 기본 구현 (체이닝 방식 예시)

class HashTable:
    def __init__(self, size=10):
        self.size = size
        self.table = [[] for _ in range(size)]

    def _hash(self, key):
        return hash(key) % self.size

    def set(self, key, value):
        index = self._hash(key)
        for i, (k, v) in enumerate(self.table[index]):
            if k == key:
                self.table[index][i] = (key, value)
                return
        self.table[index].append((key, value))

    def get(self, key):
        index = self._hash(key)
        for k, v in self.table[index]:
            if k == key:
                return v
        return None

    def delete(self, key):
        index = self._hash(key)
        for i, (k, v) in enumerate(self.table[index]):
            if k == key:
                del self.table[index][i]
                return True
        return False

4. 알고리즘에서 자주 쓰이는 해시테이블 응용 문제

4-1. 두 배열의 교집합 (Intersection of Two Arrays)

두 배열에서 공통으로 등장하는 원소를 찾는 문제입니다.

def intersection(nums1, nums2):
    set1 = set(nums1)
    result = []
    for num in nums2:
        if num in set1:
            result.append(num)
            set1.remove(num)
    return result

4-2. 해시맵을 이용한 두 수 합 문제 (Two Sum)

배열에서 합이 target이 되는 두 수의 인덱스를 찾는 문제입니다.

def two_sum(nums, target):
    hashmap = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in hashmap:
            return [hashmap[complement], i]
        hashmap[num] = i
    return []

4-3. 아나그램 그룹핑 (Group Anagrams)

단어들을 아나그램끼리 그룹으로 묶는 문제입니다.

from collections import defaultdict

def group_anagrams(strs):
    hashmap = defaultdict(list)
    for s in strs:
        key = ''.join(sorted(s))
        hashmap[key].append(s)
    return list(hashmap.values())

4-4. 해시셋으로 연속된 숫자 시퀀스 길이 구하기 (Longest Consecutive Sequence)

def longest_consecutive(nums):
    num_set = set(nums)
    longest = 0

    for num in num_set:
        if num - 1 not in num_set:  # 시작점 찾기
            length = 1
            while num + length in num_set:
                length += 1
            longest = max(longest, length)
    return longest

4-5. 해시맵으로 부분 배열 합 찾기 (Subarray Sum Equals K)

def subarray_sum(nums, k):
    count = 0
    prefix_sum = 0
    hashmap = {0: 1}

    for num in nums:
        prefix_sum += num
        if prefix_sum - k in hashmap:
            count += hashmap[prefix_sum - k]
        hashmap[prefix_sum] = hashmap.get(prefix_sum, 0) + 1
    return count

4-6. 해시맵으로 첫 번째 고유 문자 찾기 (First Unique Character in a String)

def first_unique_char(s):
    hashmap = {}
    for char in s:
        hashmap[char] = hashmap.get(char, 0) + 1

    for i, char in enumerate(s):
        if hashmap[char] == 1:
            return i
    return -1

5. 해시테이블 활용 시 주의사항

  • 충돌 발생 시 적절한 충돌 해결 방법을 선택해야 한다.
  • 해시 함수는 키를 균등하게 분포시키는 것이 중요하다.
  • 메모리 사용량과 성능 사이에 적절한 균형이 필요하다.
  • 파이썬의 기본 dict와 set은 내부적으로 해시테이블을 구현하고 있다.
728x90

'개발이야기 > 파이썬' 카테고리의 다른 글

[Python-알고리즘] 반복문과 재귀함수  (0) 2025.05.26
[Python-알고리즘] 배열과 문자열  (0) 2025.05.26
[Python-알고리즘] Linked List  (0) 2025.05.26
[Python - 알고리즘 ] 우선순위 큐  (0) 2025.05.26
[Python - 알고리즘] 큐  (0) 2025.05.26
'개발이야기/파이썬' 카테고리의 다른 글
  • [Python-알고리즘] 반복문과 재귀함수
  • [Python-알고리즘] 배열과 문자열
  • [Python-알고리즘] Linked List
  • [Python - 알고리즘 ] 우선순위 큐
Study & Stack
Study & Stack
하루하루 공부하며 개발 지식을 쌓아가는 공간입니다. 자료구조, 알고리즘, C언어, 시스템 프로그래밍까지 공부한 내용을 ‘Stack’처럼 쌓고 공유합니다.
  • Study & Stack
    Study & Stack
    Study & Stack
  • 전체
    오늘
    어제
    • 목차
      • 크래프톤정글이야기
        • 정글의기록
        • TIL - WIL
      • 개발이야기
        • C언어
        • 파이썬
        • 코딩테스트
        • CSAPP
      • 협업툴
        • git
      • 나의 이야기
        • 내돈내산
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
Study & Stack
[Python-알고리즘] 해시테이블
상단으로

티스토리툴바