1. Hash 란?
- hash는 키(key)를 특정한 값(value)로 변환하는 방식입니다.
- 데이터를 효율적으로 저장하고 검색하기 위해 사용합니다.
- 해시함수(Hash Function)을 사용하여 키를 특정한 인덱스로 매핑합니다.
- 자바에서는 hashCode() 메서드를 통해 기본적인 해시 값을 생성합니다.
public class HashExample {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "world";
System.out.println(str1.hashCode()); // 문자열 "hello"의 해시값 출력
System.out.println(str2.hashCode()); // 문자열 "world"의 해시값 출력
}
}
1) Hash 자료구조의 종류
- HashSet
- HashMap
2. 알고리즘 문제에서 해시를 활용하는 경우.
경우 | 방법 |
데이터 검색을 빠르게 해야 할 때 | HashMap - 시간복잡도 O(1) |
데이터 중복 저장을 방지해야 할 때 | HashSet |
등장 빈도/횟수를 빠르게 세야 할 때 | HashMap (key: 요소, value: 횟수) |
키-값 형태의 데이터를 저장할 때 | HashMap |
3. HashMap
- 키-값 형태로 데이터를 저장하는 자료구조
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
// 데이터 삽입 (put)
map.put("apple", 3);
map.put("banana", 5);
map.put("cherry", 7);
// 데이터 조회 (get)
System.out.println("바나나 개수: " + map.get("banana")); // 출력: 5
// 특정 키 존재 여부 확인 (containsKey)
if (map.containsKey("apple")) {
System.out.println("사과가 존재합니다.");
}
// 데이터 삭제 (remove)
map.remove("cherry");
// 전체 출력
for (String key : map.keySet()) {
System.out.println(key + " : " + map.get(key));
}
}
}
4. HashSet
- 중복을 허용하지 않는 자료구조
- 내부적으로 HashMap을 사용하여 데이터를 관리함.
- 데이터 검색, 삽입, 삭제가 평균 O(1)
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<>();
// 데이터 추가
set.add(1);
set.add(2);
set.add(2); // 중복된 값 추가 (무시됨)
set.add(3);
// 데이터 포함 여부 확인
System.out.println(set.contains(2)); // true
System.out.println(set.contains(4)); // false
// 데이터 삭제
set.remove(2);
// 전체 출력
for (int num : set) {
System.out.println(num);
}
}
}
5. Hash Collision(해시 충돌)
해시 충돌이란?
서로 다른 키가, 같은 해시값(인덱스)로 매핑되는 경우
HashCode() 결과값이 동일할 경우, eqauls() 메서드를 사용하여 두 값을 구분할 수 있다.
해시 충돌을 해결하는 방법
- 체이닝(Chaining)
- 같은 해시 값을 가지는 데이터를 연결 리스트로 관리
- 자바의 HashMap은 체이닝 방식을 사용함 - 오픈 어드레싱(Open Addressing)
- 충돌 발생 시 다른 빈 공간을 찾아 데이터를 저장하는 방식
6. Hash 자료구조의 시간복잡도 & 공간복잡도
연산 | 평균 시간 복잡도 | 최악 시간 복잡도 (해시충돌) | 공간 복잡도 |
삽입 | O(1) | O(N) | O(N) |
삭제 | O(1) | O(N) | O(N) |
탐색 | O(1) | O(N) | O(N) |
- 보통 해시 자료구조는 O(1)의 빠른 속도를 제공하지만, 해시 충돌이 많아지면 성능이 저하될 수 있다.
- 해시 테이블이 가득 차면, 성능이 저하되기 때문에 적절하게 크기를 조정해주어야 한다. (리사이징)
- 해시 함수가 고르게 분포되지 않으면 충돌이 많아져서 시간 복잡도가 O(N)까지 증가할 수 있다.
(N개의 모든 키 값에 대한 해시 함수에서 모두 충돌이 일어나는 경우) - 충돌이 적고 데이터가 균등하게 분배되는 좋은 해시 함수를 설계하는 것이 중요하다.
7. 코딩테스트에서 해시를 활용하는 전략
1 ) HashMap을 사용한 빠른 데이터 탐색
ex. 어떠한 값이 존재하는지 빠르게 확인해야할 때 (주차타워에 6666번 차량이 존재하는지)
2 ) HashSet을 사용한 중복 제거
ex. 중복 원소를 제거해야할 때 (배열에서 중복 원소 제거, 주어진 데이터에서 유일한 값 찾기)
3 ) HashMap을 사용한 빈도수 계산
ex. 각 요소의 등장 횟수를 빠르게 계산해야 할 때 (문자열 내 각 문자의 개수 세기)
'개발자 > 알고리즘' 카테고리의 다른 글
[코딩테스트-SWEA] 3차원 농부 - Java 이진 탐색 문제 풀이 (1) | 2025.04.20 |
---|---|
[코딩테스트] 코딩테스트를 준비하는 방법 - 플랫폼 (1) | 2025.02.11 |
[코딩테스트] 코딩테스트를 준비하는 방법 - 알고리즘 유형 (0) | 2025.02.07 |
[코딩테스트] 코딩테스트를 준비하는 방법 - 프로그래밍 언어 (2) | 2025.02.06 |