https://aeongiii.tistory.com/87
이전에 HashSet를 사용해 풀이했는데 이번에는 다른 방법으로 풀어보려고 한다.
결과부터 비교해보면 아래 표와 같다.
| 기존 풀이 방식 (HashSet) | 새로운 풀이 방식 (이분 탐색) | |
| 탐색 방식 | HashSet.contains() 사용 | Arrays.sort() 후 이분탐색 |
| 시간복잡도 | O(N+M) | O(N log N + M log N) |
| 메모리 사용 | hashset에 저장, O(N) | 배열에 저장하는 방식, O(N) |
| 출력 | BufferedWriter | StringBuilder -> System.out.println() |
| 장점 | 탐색 속도 매우 빠름(O(1)) 정렬 필요 없음 |
메모리 적게 사용 정렬한 뒤에는 효율적 |
| 단점 | HashSet의 O(N) 메모리 사용량 해시 충돌이 많아질경우 성능 저하 |
정렬하는 O(N log N) 시간 필요 이분탐색이 반복되므로 탐색 비용 증가 |

1. 문제 분석
1) 각 테스트케이스에서 '수첩 2'에 적인 숫자 순서대로 '수첩1'에 적혀있으면 1을, 없으면 0을 출력한다.
2. 제약 조건
1) 1 <= N <= 1,000,000
2) 1 <= M <= 1,000,000
3) 모든 정수의 범위는 int
3. 최초 의사결정
1) 수첩 2에 적인 내용을 순서대로 출력하면서도 수첩1에 있는지 없는지를 다 확인해야 하므로, 정렬+이분탐색을 사용해 시간복잡도를 줄인다.
2) T를 받고 각 T에 대해
3) N을 받고 N배열에 저장, M을 받고 M배열에 저장한다.
4) N배열을 sort한다.
5) M을 하나씩 돌면서 이분탐색을 한다. (start, end, target)
- half = end/2로 두고, target < half이면 0~half-1까지로 범위 변경한 뒤 다시 실행
- half = End/2로 두고, target > half이면 half+1~0까지로 범위 변경한 뒤 다시 실행
- half = M일 경우 끝
4. 문제풀면서 수정한 부분
1) 재귀함수를 호출하기 전에 N <= half 여부를 검사하여 인덱스 초과 예외도 줄이고 0이 많이 붙는 오류도 수정했다.
2) 메모리 초과 문제 : String[]을 int[]로 변경
3) start = end가 될 경우 half도 계속 똑같아서 무한 루프에 빠질 수 있다. N <= half보다는 start>end가 더 적절하다.
4) 메모리를 줄이기 위해 재귀가 아닌 while 반복문으로 범위를 줄여간다.
5) 테스트케이스마다 sb 초기화

N과 M의 크기가 크고 빠른 탐색이 필요한 문제이므로 HashSet이 더 유리할 것 같다.
만약 N배열이 이미 정렬된 상태로 주어지거나, 메모리가 제한적이라면 이분 탐색을 사용해야 할 것이다.
| 1244. 스위치 켜고 끄기 (0) | 2025.03.08 |
|---|---|
| 1463. 1로 만들기 (0) | 2025.02.25 |
| 15649. N과 M(1) (0) | 2025.02.23 |
| 25178. 두라무리 휴지 (0) | 2025.02.23 |
| 10610. 30 (0) | 2025.02.22 |