정렬 후 회전된 배열 2.2_(a)
입력으로 주어지는 배열A [0..n-1]은 오름차순으로 정렬되어 있으며
n개의 서로 다른 정수들을 원소로 가진다.
즉, A[0] < A[1] < … < A[n-1] 이다.
원소들은 양수, 음수 혹은 0 일 수 있다.
(a) A[i] = i를 만족하는 index i가 존재하는지 알고 싶다.
그런 index i가 존재하면 찾아서 i를 출력하고,
없으면 -1을 출력하는 알고리즘을 설계하고 분석하시오.
A = [1,2,3,4,5] #대상이 되는 배열
# A : 배열, F : 배열의 처음 원소의 인덱스 번호, E : 배열의 마지막 원소의 인덱스 번호
def SamePosAndVal(A,F,E):
M = (F+E) // 2 # 배열의 중간 원소의 인덱스 번호
if (A[0] == 0): # 배열의 처음이 0인 경우에, 0을 return
return 0
if (F > E): # 배열의 마지막 원소의 인덱스 번호가 배열의 처음 원소의 인덱스 번호보다 작다면,
return -1 # 조건에 해당하는 원소가 존재하지 않는다는 반증이기 때문의 -1을 return한다.
if (A[M] < M): # 중간 원소의 인덱스 번호보다 A[M]의 값이 더 작다면, 중간 원소의 앞부분에는 찾는 원소가 존재하지 않는다는 반증이기 때문에
return SamePosAndVal(A,M+1,E) # 배열의 중간 원소의부터 마지막 원소까지를 재귀호출의 배열로 사용한다.
elif(A[M] > M): # 위의 반대의 경우, 중간 원소의 앞에 해당하는 원소가 있기 때문에 중간 원소를 기준으로 앞의 남아있는 배열을
return SamePosAndVal(A,F+1,M) # 다음 재귀호출의 대상으로 삼는다.
else:
return M # 그리고 나머지의 경우에는 A[M]과 M의 원소가 같은 경우이기 때문에 조건에 해당하는 원소를 찾은 것이므로 M을 return한다.
print(SamePosAndVal(A,0,len(A)-1))
시간 복잡도 : T(n) = T(n/2) + O(1) = O(logn).
정확성 : 문제의 해당하는 조건을 갖춘 원소들은 모두 해결할 수 있기 때문에 정확성은 100%이다.
(b) 배열 A 의 원소들이 모두 0 혹은 양수라는 조건이 성립한다면, 위의 문제를 해결하는 더 빠른 알고리즘이 가능하다. 어떻게 할 수 있을까?
해당하는 배열의 원소 첫번째 인덱스[0]가 원소 0이 아니라면, 문제의 조건이 서로 다른 양수이기 때문에 뒤에 있는 원소들은 모두 조건을 만족할 수 없다는 반증이 나온다.
때문의 시간복잡도는 O(1)이 나오게 되며, a의 시간 복잡도 보다 빠르게 해결이 가능하다.