n개의 원소를 포함하고 있는 수열이 오름차순 으로 정렬되어 있습니다. 이때 이 수열에서 x가 등장하는 횟수를 계산하세요. 예를 들어 수열 [1, 1, 2, 2, 2, 2, 3]이 있을 때 x = 2라면, 현재 수열에서 값이 2인 원소가 4개 이므로 4를 출력합니다.
단, 이문제는 시간 복잡도 O(logN)으로 알고리즘을 설계하지 않으면 '시간 초과' 판정을 받습니다.
입력예시 1
7 2
1 1 2 2 2 2 3출력예시 1
4
입력예시 2
7 4
1 1 2 2 2 2 3출력예시 2
-1
시간 복잡도를 O(logN)로 정하고 정렬된 리스트 안에서 특정 수를 찾는 문제이니 이진탐색을 이용하는 것이 좋다. 다만 이때, 첫번째와 마지막으로 해당 수가 나오는 인덱스를 구하는 함수를 작성하도록 한다.
또 다른 풀이로 라이브러리를 이용하는 것인데 해당 수가 중복되어 나오면 가장 빠른 인덱스를 반환하는 bisect_left 가장 나중 인덱스를 반환하는 bisect_right 함수를 이용한다.
def first(arr, target, start, end):
if start > end:
return None
mid = (start + end) // 2
# mid가 가장 앞에 있거나, 미드 앞 값이 target 보다 작을 때
if (mid == 0 or target > arr[mid - 1]) and arr[mid] == target:
return mid
elif arr[mid] >= target:
return first(arr, target, start, mid - 1)
else:
return first(arr, target, mid + 1, end)
def last(arr, target, start, end):
if start > end:
return None
mid = (start + end) // 2
# mid가 가장 뒤에 있거나, mid 뒤 값이 target 보다 클 때
if (mid == n - 1 or target < arr[mid + 1]) and arr[mid] == target:
return mid
elif arr[mid] >= target:
return first(arr, target, start, mid - 1)
else:
return first(arr, target, mid + 1, end)
n, x = map(int, input().split())
arr = list(map(int, input().split()))
a, b = first(arr, x, 0, n - 1), last(arr, x, 0, n - 1)
if a == None or b == None:
print(-1)
else:
print(b - a + 1)
from bisect import bisect_left, bisect_right
def count_by_range(arr, left_value, right_value):
right_index = bisect_right(arr, right_value)
left_index = bisect_left(arr, left_value)
return right_index - left_index
n, x = map(int, input().split())
arr = list(map(int, input().split()))
if count_by_range(arr, x, x) == 0: print(-1)
else:
print(count_by_range(arr, x, x))