[BOJ] 2230 수 고르기

정렬, 두 포인터


해당 문제는 입력의 개수가 10만개 이므로 O(N^2) 알고리즘을 사용할 경우 시간초과가 난다. 따라서 O(NlogN)이하 알고리즘을 사용해야겠다고 판단.

O(NlogN) 중 어떤 알고리즘을 사용하는게 좋을지 고민해보았다. 10만개의 데이터를 순회하며 해당 데이터 +-m을 타겟으로 하여 이진 탐색을 해서 풀어도 좋을 것 같아서 시도를 해보았으나 구현의 까다로움이 있어 다른 방법을 모색해보았다.

이진 탐색을 하기위해 앞서 데이터를 정렬했는데, 정렬하고 보니 head, tail 두 개의 포인터를 사용하여 두 데이터의 차이를 계속 비교하며 10만의 데이터를 2번 순회하도록 구현할 수 있다는 것을 깨달았고 코드는 아래와 같다.

import sys

def solution(numbers, n, m):
    _min = 2000000001
    numbers.sort()
    head, tail = 0, 0
    while True:
        tmp = numbers[head] - numbers[tail]
        if tmp == m:    # m이랑 똑같은 경우는 stop
            _min = tmp
            break
        if tmp < m:     # 만약 기준 미달이면 헤드 이동
            if head == n-1:     # head 가 끝인데 기준미달이면 종료
                break
            head += 1
        elif tmp > m:   # 기준에 부합하는 경우
            if tmp < _min:      # 기존 최소값보다 작은 경우
                _min = tmp
            tail += 1

    return _min

if __name__ == "__main__":
    N, M = map(int, sys.stdin.readline().rstrip().split())
    A = [0] * N
    for i in range(N):
        A[i] = int(sys.stdin.readline().rstrip())
    print(solution(A, N, M))

태그:

카테고리:

업데이트: