973. K Closest Points to Origin

  • 며칠전 풀었던 문제와 비슷하게, closest K 가 조건인 만큼, PQ 를 이용하면  될것 같아서 접근했고, compile 에러 ( pq.size() 에서 () 빼먹음, cnt++;  에서 ; 빼먹음)  을 빼면 한번에 accept 되었다.
  •  closest K 를 구하는 만큼, max heap 을 이용하는 것이 포인트 이다. 
  • time complexity 는 PQ 에 point  개수 N 개 만큼 insert 했으므로, O(NlogN) 이 되는것 같다.
  • 하지만 내 풀이는 28ms 로, 매우 오래 걸렸다.
  • 다시 보니, 전체 points  를 모조리 정렬하지 않았으므로  O(NlogN)이 아닌, O(NlogK) 가 된다. K 개의 PQ  를 관리 하였기 때문이다.
  • 어떤이가 Top K 접근법에 대해 잘 정리해둔 글이 있어, 요약한다.

Top K 접근법

1. 정렬이다. 모조리 정렬 후  K 개를 찾는 것으로, 
  • 직관적이고 코드 길이가 매우 짧다
  • 하지만 매우 비효율적이며, 이미 나온 앞의 항목들도 모조리 들고 있어야 한다는 점,으로  real-time 에서는 사용할 수 없다.
  • O(NlogN) 이 된다.
2.  Max Heap with K size 를 이용한다. 내가 한 방법으로,
  • real-time online (stream)  데이터에서도 적용 가능하고, 이전의 데이터 사이즈에 대해 알 필요가 없는것이 장점이다.
  • 가장 효율적인 솔루션은 아니다.(!)
  • 이론적으로 O(NlogK) 가 된다.
3. QuickSelect 를 이용한다. 들어는 본 적이 있는 방법으로,
  • QuickSort 와 비슷하게, pivot 을 정해서, pivot 보다 크면 오른쪽으로, 작으면 왼쪽으로 몰아 넣고 pivot 이 들어갈 자리를 찾는 방식이다.
  • QuickSort 는 Average O(NlogN), Worst O(N^2) 의 복잡도를 갖지만,
  • QuickSelect  는 top K 개를 찾으므로,  pivot 의  한쪽에만 관심이 있다.
  • 이론적으로, QuickSelect 는 Average O(N), Worst O(N^2) 이다.
  • 장점으로는 3개 방법중 제일 효율적이지만
  • Worst 인 경우 N^2 라는 점, K 개의 결과가 정렬되지는 않는다는 점이 있다.

QuickSelect 는 한번 봐서 이해는 안되고, 계속 봐야 할것 같다.

public int[][] kClosest(int[][] points, int K) {
int len = points.length, l = 0, r = len - 1;
while (l <= r) {
int mid = helper(points, l, r);
if (mid == K) break;
if (mid < K) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return Arrays.copyOfRange(points, 0, K);
}

private int helper(int[][] A, int l, int r) {
int[] pivot = A[l];
while (l < r) {
while (l < r && compare(A[r], pivot) >= 0) r--;
A[l] = A[r];
while (l < r && compare(A[l], pivot) <= 0) l++;
A[r] = A[l];
}
A[l] = pivot;
return l;
}

private int compare(int[] p1, int[] p2) {
return p1[0] * p1[0] + p1[1] * p1[1] - p2[0] * p2[0] - p2[1] * p2[1];
}

참조 https://leetcode.com/problems/k-closest-points-to-origin/discuss/220235/Java-Three-solutions-to-this-classical-K-th-problem.

Comments

Popular posts from this blog

삼성전자 무선사업부 퇴사 후기

코드리뷰에 대하여

개발자 커리어로 해외 취업, 독일 이직 프로세스