import sys
sys.stdin=open('input.txt', 'r')
input = sys.stdin.readline
if __name__=="__main__":
n = int(input())
arr = list(map(int, input().split()))
sorted_arr = sorted(list(set(arr)))
'''
[2, 4, -10, 4, -9] -> [-10, -9, 2, 4] : 자신의 위치가 곧 답이 됨
'''
for i in arr:
start = 0
end = len(sorted_arr) - 1
while start <= end:
mid = (start + end) // 2
if sorted_arr[mid] == i:
print(mid, end=' ')
break
elif sorted_arr[mid] < i:
start = mid + 1
else:
end = mid - 1
오름차순으로 정력 sorted를 하면 자신의 위치가 곧 자기보다 작은 수의 개수가 된다.
import sys
sys.stdin=open('input.txt', 'r')
input = sys.stdin.readline
if __name__=="__main__":
n = int(input())
arr = list(map(int, input().split()))
sorted_arr = sorted(list(set(arr)))
'''
[2, 4, -10, 4, -9] -> [-10, -9, 2, 4] : 자신의 위치가 곧 답이 됨
'''
for i in arr:
print(sorted_arr.index(i), end=' ')
이렇게 하면 간단하지만 시간초과가 발생한다. 주어지는 숫자 범위가 어마어마한것을 알수 있다
list.index(i)의 형태는 시간복잡도O(N)➡️매번 최대1,000,000번의 수행이 되면서시간초과
{ dict[요소] : 요소의 index }의 형태 시간 복잡도O[1]➡️ 매번 최대 입력 수 만큼 수행
따라서 이번에 딕셔너리를 사용해보자
딕셔너리 사용
import sys
sys.stdin=open('input.txt', 'r')
if __name__=="__main__":
n = int(input())
arr = list(map(int, input().split()))
sorted_arr = sorted(list(set(arr)))
dic = {sorted_arr[i] : i for i in range(len(sorted_arr))}
for i in arr:
print(dic[i], end = ' ')
'''
[2, 4, -10, 4, -9] -> [-10, -9, 2, 4] : 자신의 위치가 곧 답이 됨
{-10: 0, -9: 1, 2: 2, 4: 3} 각 수가 자신의 위치를 딕셔너리로 저장
'''
이분탐색 2
import sys
sys.stdin=open('input.txt', 'r')
from bisect import bisect_left
if __name__=="__main__":
n = int(input())
x_list = list(map(int, input().split()))
sorted_x_list = sorted(list(set(x_list)))
for x in x_list:
# x에 대해 x보다 작은 값은 x보다 왼쪽에 있는 숫자들의 수를 출력
print(bisect_left(sorted_x_list, x), end=" ")
bisect는 참 사용할거 같지 않아서 외우지도 않고 외운다 해도 막상 쓸때 떠오를것 같지 않아서 안외웠는데 이럴때 딱 쓸 수 있다.
bisect : 파이썬에서 이진 탐색을 쉽게 구현할 수 있도록 bisect 라이브러리를 제공. "정렬된 배열"에서 특정한 원소를 찾아야할 때 매우 효과적으로 사용.