2014-02-23 1 views
4

나는 인터뷰에서이 질문을 받았다. O (n) 시간에 분명히 할 수 있었지만 O (logn)에서 해결할 방법을 생각하지 않았습니다. 몇 가지 divide-and-conquer 알고리즘을 사용하는 것처럼 들리지만 잘 모르겠습니다.2 개의 정렬 된 정수 배열을 가지고 있는데, O (logn) 시간에 k 번째로 큰 항목을 찾는 방법은 무엇입니까?

+0

O (n)에서 어떻게 진행했는지 알려줄 수 있습니까? 둘 사이에서 앞뒤로 뛰는 곳이 어디죠? – ChiefTwoPencils

+2

솔직히 O (k)보다 작을 수는 없습니다. 두 배열의 마지막 요소를 비교하고 두 항목 중 가장 큰 배열과 연관된 인덱스를 줄입니다. k 번 해보세요. k 번째 가장 큰 요소가 있습니다. –

답변

7

둘 다 크기 k로 잘립니다. 필요하다면, 하나 또는 양쪽 배열의 끝에 무한대가 충분히있어 크기 k를 갖도록 프로그램을 작성하게하십시오. 이것은 점근 런타임에 영향을 미치지 않습니다. 실제 구현에서는 좀 더 효율적인 작업을 수행 할 수 있습니다.

그런 다음 각 배열의 k/2 번째 요소를 비교합니다. 요소를 동일하게 비교하면 k 번째 요소를 찾았습니다. 그렇지 않으면, 더 낮은 k/2 번째 요소를 갖는 배열을 A로하고 다른 배열을 B로 놓습니다. A의 아래쪽 절반과 B의 위쪽 절반을 버리고 남은 것의 k/2 번째 요소를 재귀 적으로 찾습니다. k = 1을 명중하면 멈 춥니 다.

모든 단계에서 A의 아래쪽 절반이 너무 작게 보장되고 B의 위쪽 절반이 너무 크게 보장됩니다. 남아있는 k/2 번째 요소는 A의 아래쪽 절반보다 더 크게 보장되므로 원본의 k 번째 요소가 될 것입니다. 파이썬에서 개념의

증명 :

def kth(array1, array2, k): 
    # Basic proof of concept. This doesn't handle a bunch of edge cases 
    # that a real implementation should handle. 
    # Limitations: 
    # Requires numpy arrays for efficient slicing. 
    # Requires k to be a power of 2 
    # Requires array1 and array2 to be of length exactly k 
    if k == 1: 
     return min(array1[0], array2[0]) 
    mid = k//2 - 1 
    if array1[mid] > array2[mid]: 
     array1, array2 = array2, array1 
    return kth(array1[k//2:], array2[:k//2], k//2) 

나는하지만 많은이를 테스트했습니다.

+0

그 소리 같네요. +1. –

+1

* 요소가 동일하면 비교해서 임의로 선택하십시오. * : 둘 다 같으면 가장 큰 k 번째 요소를 찾지 못했습니까? –

+0

@JBNizet : 네가 맞다고 생각해. – user2357112

관련 문제