PS/BOJ&Programmers

[백준/1158] 요세푸스 문제 | 파이썬 연결리스트 | N번째 원소

sebinChu 2025. 2. 13. 18:30

요세푸스 문제


2년 전 풀었던 요세푸스...! 다시 풀려니까 로직은 생각나는데 정확한 구현이 떠오르지 않아 다시는 까먹지 않으려고 포스팅한다. (문제 바로 가기)

 

알고리즘


순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다.

 

계속 해서 K 번째 사람을 제거하는데, 여기서 문제는 제거된 K를 제외하고 배열을 재생성해야 한다.

  • 이 문제의 연산 범위는 (1 ≤ K ≤ N ≤ 5,000)이며, Python은 1초에 약 5천만번의 연산이 가능하다.
  • 배열 순회하면서 K를 찾고, 배열을 재생성해도 O(N**2) 즉, 5000**2 = 2500만번 정도 수행한다.
  • 따라서 연산마다 배열을 재생성해도 충분한 시간이다.

 

전체 코드


import sys;input=sys.stdin.readline

# 1. 값을 [0] + 입력으로 받아서 인덱스가 1부터 시작하도록
n,k = map(int, input().split())
li = [i for i in range(1, n+1)]

# 2. 인덱스 값을 (idx+k)%k
idx = 0
res = []
for _ in range(n):
    # 요세푸스 순열 규칙으로 리스트를 순회하기 위한 인덱스 점화식
    idx += (k-1)
    idx %= len(li)

    # 요세푸스에 따른 새로운 순열 생성
    res.append(str(li[idx]))
    li.pop(idx) # O(N)

print("<", ', '.join(res), ">", sep="")

 

알게된 점 및 정리


  • 리스트'N번째' 인덱스는 %len(arr) 형태구할 수 있다.
  • 파이썬의 pop()은 파라미터가 없으면 리스트 마지막 요소를 추출하며 복잡도는 O(1)
    • pop(i)와 같이 파라미터 값을 주면 복잡도는 O(N)
    • 파이썬은 배열이 없고 연결 리스트이므로, 연결 리스트의 검색 연산 복잡도를 갖는다.