문제
두 수의 합
주어진 수열에서 두 원소를 골라 k와 합이 가장 가까운 모든 경우를 찾는 문제입니다.
풀이
$n$의 크기가 최대 $10^6$이므로 모든 경우를 탐색하면 $O(n^2)$으로 시간초과를 받게 됩니다. 따라서 모든 경우를 탐색하는 것이 아니라 조건을 만족하게끔 그리디하게 탐색해야 합니다.
방법에는 두가지가 있는데, 하나는 정렬+이분탐색이고, 하나는 정렬+두 포인터입니다. 이분탐색을 이용하면 $O(2nlogn)$이고, 두 포인터를 이용하면 $O(nlogn + n)$으로 조금 더 빠릅니다. 이 글에서는 두 포인터로 풀이해 보겠습니다.
먼저 주어진 수열을 정렬합니다. ($O(nlogn)$)
그리고 포인터 두개를 수열의 처음, 끝에 각각 지정합니다. 만약 두 포인터가 가리키는 두 수의 합이 k보다 작다면 왼쪽 포인터를 오른쪽으로 옮겨 합이 커지게끔 합니다. k보다 크다면 반대로 오른쪽 포인터를 왼쪽을 옮기면 됩니다. ($O(n)$)
다만 가장 가까운 모든 경우의 수를 찾아야 하므로, k와 두 수의 합의 차를 저장해 둡니다. 포인터를 옮겨가며 탐색하다가 차가 같다면, 경우의 수를 하나 늘려주면 되고, 차가 작다면 경우의 수를 1로 초기화 해주면 됩니다.
코드
1 |
|