2012-09-23 4 views
4

숫자가 주어지면, 그 총합이 그 숫자와 같은 배열에서 가능한 모든 인덱스 쌍을 찾아야합니다. 현재 다음 알 고를 사용 중입니다.주어진 합계로 쌍을 열거하는 데 더 나은 알고리즘 (dict 사용보다).

def myfunc(array,num): 
    dic = {} 
    for x in xrange(len(array)): # if 6 is the current key, 
     if dic.has_key(num-array[x]): #look at whether num-x is there in dic 
      for y in dic[num-array[x]]: #if yes, print all key-pair values 
       print (x,y), 
     if dic.has_key(array[x]): #check whether the current keyed value exists 
      dic[array[x]].append(x) #if so, append the index to the list of indexes for that keyed value 
     else: 
      dic[array[x]] = [x] #else create a new array 

O(N) 시간에 실행됩니까? 그렇지 않다면 무엇을해야 그렇게 할 수 있습니까? 그리고 어떤 경우 든 보조 데이터 구조를 사용하지 않고 O(N) 시간에 실행할 수 있습니까?

+6

화제가 아닌 것은 무엇을 의미합니까? 코드를 제공하지 않는 솔루션을 요구하면 연구를 보여주지 않아 벌칙이 부과됩니다. 그렇게 할 때 마이그레이션해야한다고 말합니까? – SexyBeast

+2

@vascowhite (및 다른 유권자) : FAQ 중 특히 "위반하는"부분은 무엇이라고 생각하십니까? FAQ에서 : '실제 문제를 기반으로 실용적이고 답할만한 질문을해야합니다.' 그는 문제와 그의 시도를주고있다. 그는 또한 특정 범위의 질문을 질문합니다 (복잡성은 무엇입니까? O (n)보다 더 잘할 수 있습니까?) – amit

+0

질문이 없지만 합이 같은 모든 쌍을 찾고 싶다면 정정하십시오. 그 쌍보다 주어진 수는 개별적으로 그 수보다 작아야합니다. 그래서, 만약 당신이'[1,2,3,4,5,6,7,8,9,10]'리스트를 받았고'sum == 6 '을 갖는 모든 쌍을 찾을 수 있다고 가정 해 봅시다. 먼저 목록을'[1,2,3,4,5,6]으로 필터링하고 그 쌍을 찾는다. – RanRag

답변

6

O (N) 시간에 실행됩니까?

예 아니오. 복잡성은 실제로 O(N + M)이고 M출력 크기가입니다.
아쉽게도 출력 크기는 O(N^2)입니다. 예를 들어 배열 [3,3,3,3,3,...,3]number == 6과 같이 최악의 경우입니다. 생산에 필요한 요소의 수가 2 진수가됩니다.

그러나 점진적으로 말하자면 입력 크기와 출력 크기가 선형이기 때문에 더 잘 수행 할 수 없습니다.

+0

조금 더 자세히 설명해 주시겠습니까? 나에게 완전히 명확하지 않다. 비슷한 해결책이 http://www.ardendertat.com/2011/09/17/programming-interview-questions-1-array-pair-sum/에 있습니다. 더 잘 수행 될 것이라고 생각하십니까? – SexyBeast

+0

@Cupidvogel : 링크 된 솔루션이 정확하지 않다고 생각합니다. 중복 요소를 처리하지 않으므로 원하는 것입니다. 링크 된 솔루션은'O (nlogn)'시간과'O (1)'공간에서 실행되지만 모든 중복 요소를 출력하지는 않습니다. – amit

+0

어떻게 링크 된 솔루션이'O (log N)'시간에 작동합니까? – SexyBeast

3

배열 참조를 사용하여 O (N) 시간에 실제로 실행되는 매우 간단한 솔루션입니다. 모든 출력 쌍을 열거하려면, 물론 (amit 음으로) 최악의 경우 O (N^2)를 취해야합니다.

from collections import defaultdict 
def findpairs(arr, target): 
    flip = defaultdict(list) 
    for i, j in enumerate(arr): 
     flip[j].append(i) 
    for i, j in enumerate(arr): 
     if target-j in flip: 
      yield i, flip[target-j] 

후 처리는 출력 값을 모두 얻을 수 (및 (i,i) 답변을 걸러 일) :

def allpairs(arr, target): 
    for i, js in findpairs(arr, target): 
     for j in js: 
      if i < j: yield (i, j) 
+0

그러나이 솔루션은 다소 파이썬 특정입니다. 나는 좀 더 휴대용 솔루션을 생각하고 있었다. – SexyBeast

+0

파이썬에 한정되지 않습니다. 연결된 목록의 해시 테이블 (O (1) 조회를위한 해시 테이블, 원하는 목록의 머리를 참조 할 수있는 링크 된 목록)을 사용하여 다른 언어로 구현할 수 있습니다. – nneonneo

+0

offtop : 'arr'이 임의의 반복 가능하도록 허용 : 'flip for j'의 경우 : flip의 target-j 인 경우 : flip [j], flip [target-j]'i의 목록을 'j'의 목록 ('allpairs()'에 압축 풀기) – jfs