-
[Python] BOJ 1269 대칭차집합코딩테스트/백준 2025. 2. 6. 15:29
https://www.acmicpc.net/problem/1269
요구사항
- 시간 제한: 2초
- 메모리 제한: 256MB
결론: 각 집합의 원소의 개수 200,000. 약 2억까지 괜찮으니 O(N**2)아래로 가자.
설계 1 (최종 답안은 설계 3을 참고해주세요.)
- a = [1, 2, 4]
- b = [2, 3, 4, 5, 6]
- a를 순회하며 b가 있는 지 체크 한다. count_a += 1
- b를 순회하며 a가 있는 지 체크한다. count_b += 1
- print(count_a + count_b)
import sys input = lambda: sys.stdin.readline().rstrip() a_size, b_size = map(int, input().split()) a = list(map(int, input().split())) b = list(map(int, input().split())) count_a = 0 count_b = 0 for i in b: if i not in a: count_a += 1 for i in a: if i not in b: count_b += 1 print(count_a + count_b)
- 위 방법 시간 초과가 난다.
- 이 때는 2번의 for문으로 시간초과가 난다고 생각하였음.
- 하나의 for문으로 어떻게 구현하지 생각함.
설계 2
- a = [1, 2, 4]
- b = [2, 3, 4, 5, 6]
- 둘의 공통은 2와 4 총 2개이다.
- len(a) - 2 + len(b) - 2 = 4이다.
- 즉, 한 번의 for문으로도 구현 가능
import sys input = lambda: sys.stdin.readline().rstrip() a_size, b_size = map(int, input().split()) a = list(map(int, input().split())) b = list(map(int, input().split())) count = 0 for i in b: if i in a: count += 1 print(len(a) + len(b) - (count * 2))
- 여전히 시간초과 발생.
- 문제는 for문이 2개냐 1개냐의 문제가 아니였음...
- for i in b 에서 O(M) 이 걸린다고 치자.
- if i in a -> 비교만 해서 O(1)이라고 생각했는 데, 반만 맞다. 비교 자체는 O(1)이겠지만, a를 순회할 거니깐. O(N)
- 따라서 O(M * N) 의 시간복잡도를 갖는다. 즉, 요구사항인 2초를 훌쩍 넘어버리는 것.
설계 3
- a와 b 를 list가 아닌 set 자료구조로 받는다.
- 그 이유는 수학에서 집합은 서로 다른 원소들의 모임이기 때문에 집합을 허용하지 않는다.
- 파이썬의 set은 해시 테이블 기반으로 구현. 탐색, 추가, 삭제 연산이 평균적으로 O(1)
- set 자료구조는 교집합 연산을 제공한다. O(min(N, M)
- 작은 쪽을 기준으로 각 원소를 큰 쪽에서 찾기 때문
- a = {1, 2, 4}
- b = {2, 3, 4, 5, 6}
- a & b # {2, 4}
- 참고) 한 집합의 크기가 매우 크고 다른 집합의 크기가 매우 작다면, 작은 집합의 우너소를 하나씩 큰 집합에서 검색하는 것이 더 효율적일 수 있다.
import sys input = lambda: sys.stdin.readline().rstrip() a_size, b_size = map(int, input().split()) a = set(map(int, input().split())) b = set(map(int, input().split())) print((len(a) + len(b)) - (len(a & b) * 2) )
회고
set 자료구조에 대해 리마인드 할 수 있어서 좋았다. 특히, set 자료구조에서 & method 는 충격적이다.
헷갈리는 용어
메서드 vs 라이브러리 vs 프레임워크
- 메서드란 객체에 속한 함수. 특정 객체(클래스의 인스턴스)가 사용하는 함수. 예를 들어, list.append(), set.intersection()
- 라이브러리란: 여러 개의 메서드, 클래스 등을 모아둔 코드 집합 import math,,
- 프레임워크: 코드의 뼈대를 제공하고, 거기에 코드를 추가하는 구조
'코딩테스트 > 백준' 카테고리의 다른 글
[Python] BOJ 1406 에디터 (0) 2025.02.20 [Python] BOJ 11728 배열 합치기 (0) 2025.02.06 [Python] BOJ 8595 히든넘버 (0) 2025.02.03 [Python] BOJ 28278 스택 2 (0) 2025.02.02 [Python] BOJ 7562: 나이트의 이동 (1) 2024.11.27