새소식

반응형
알고리즘(백준)/백준

[Baekjoon | 백준] 18870번. 좌표압축 (파이썬/정렬)

2023.03.12
  • -
반응형

 

 

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다.

Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다.

X1, X2, ..., XN에 좌표 압축을 적용한 결과 X'1, X'2, ..., X'N를 출력해보자.

 

입력

첫째 줄에 N이 주어진다.

둘째 줄에는 공백 한 칸으로 구분된 X1, X2, ..., XN이 주어진다.

 

출력

첫째 줄에 X'1, X'2, ..., X'N을 공백 한 칸으로 구분해서 출력한다.

 

제한

  • 1 ≤ N ≤ 1,000,000
  • -109 ≤ Xi ≤ 109

 

 

예제 입력 1

5
2 4 -10 4 -9

예제 출력 1

2 3 0 3 1

예제 입력 2

6
1000 999 1000 999 1000 999

예제 출력 2

1 0 1 0 1 0

 

알고리즘 분류

  • 정렬
  • 값 / 좌표 압축

 

풀이 방식

문제를 보고 가장 먼저 떠오르는 방식은 2중 for문으로 푸는 O(N^2) 풀이 방식이다. 하지만 제한을 보면 알겠지만 N의 범위가 1,000,000이기 때문에 O(N^2)의 풀이는 시간초과가 뜰 것이다.

 

 

1번 풀이: 시간초과

그래도 일단 O(N^2) 풀이로 풀어본 방식이고 역시나 시간초과가 발생하였다..

 

import sys
input = sys.stdin.readline

N = int(input())

arr = list(map(int, input().split()))

answer = []
for i in range(len(arr)):
    count = 0
    for j in range(len(arr)):
        if i == j: continue
        if arr[i] > arr[j]: count += 1
    answer.append(count)
    
print(*answer)

 

 

2번 풀이: 성공

bisect 모듈을 활용하여 for문을 돌면서 각 원소가 들어갈 위치(index)를 answer 리스트에 append 해 주는 식으로 구현을 했다.

하지만 중복이 있으면 들어갈 index가 뒤로 밀려버리기 때문에 set을 하나 정의해서 해당 set에서 bisect 인덱스를 찾는 코드를 구현했다.

import sys
from bisect import bisect_left
input = sys.stdin.readline

N = int(input())

arr = list(map(int, input().split()))


tmp = []
for i, v in enumerate(arr):
    tmp.append([i, v])

arr.sort()
arr_set = list(set(arr))
tmp.sort(key=lambda x: x[1])
arr_set.sort()

answer = [0] * N
for i in range(len(arr)):
    idx = bisect_left(arr_set, arr[i])
    answer[tmp[i][0]] = idx

print(*answer)

 

다른 풀이

내가 푼 풀이와 유사하지만 쓸모 없는 부분을 최대한 줄여서 푼 방식이다.

import sys

input = sys.stdin.readline

n = int(input())
arr = list(map(int, input().split()))

arr2 = sorted(list(set(arr)))
dic = {arr2[i] : i for i in range(len(arr2))}
for i in arr:
    print(dic[i], end = ' ')

set 집합을 정렬한 리스트를 하나 정의 하는 것까지는 똑같은데 딕셔너리를 활용하면 쉽게 구현이 가능하다.

딕셔너리의 key값이 set 리스트의 원소이고 value가 리스트의 길이 range iterable 객체로 하면 각 key에 대해 위치를 저장할 수 있게되므로 arr에 대해 for문을 하나씩 돌면서 딕셔너리에서 각 원소를 key로 하는 value를 출력하면 된다.

 

 

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.