[ Programmers / CodingTest / Python ] n^2 배열 자르기

황승환·2022년 1월 21일
0

Python

목록 보기
113/498

문제 설명

정수 n, left, right가 주어집니다. 다음 과정을 거쳐서 1차원 배열을 만들고자 합니다.

  1. n행 n열 크기의 비어있는 2차원 배열을 만듭니다.
  2. i = 1, 2, 3, ..., n에 대해서, 다음 과정을 반복합니다.
    • 1행 1열부터 i행 i열까지의 영역 내의 모든 빈 칸을 숫자 i로 채웁니다.
  3. 1행, 2행, ..., n행을 잘라내어 모두 이어붙인 새로운 1차원 배열을 만듭니다.
  4. 새로운 1차원 배열을 arr이라 할 때, arr[left], arr[left+1], ..., arr[right]만 남기고 나머지는 지웁니다.

정수 n, left, right가 매개변수로 주어집니다. 주어진 과정대로 만들어진 1차원 배열을 return 하도록 solution 함수를 완성해주세요.

제한사항

  • 1 ≤ n ≤ 107
  • 0 ≤ left ≤ right < n2
  • right - left < 105

입출력 예

n	left	right	result
3	2	5	[3,2,2,3]
4	7	14	[4,3,3,3,4,4,4,4]

접근 방법

처음에는 단순하게 문제에서 주어진 대로 차근차근 코드를 작성하였다. n의 범위가 10^7이기 때문에 당연히 시간 초과가 발생하였다. 그 다음 시도로는 2중 for문을 하나의 for문으로 줄이고 tmp=list(range(1, n+1))배열을 미리 생성한 뒤에 배열에 [i]*i+tmp[i:]를 더하여 배열 전체를 구현하고 슬라이싱으로 값을 반환하도록 하였다. 이번에는 절반정도의 케이스에서 시간초과가 발생하였다. 그러던 중에 규칙을 발견하였다.

arr[i]는 i를 n으로 나눈 몫과 나머지 중 더 큰 값 + 1을 취하게 된다.
이 규칙을 적용하기 위해 divmod() 함수를 사용하였다. divmod() 함수는 첫번째 인자를 두번째 인자로 나눈 몫, 나머지를 나란히 반환한다. 이를 통해서 반복의 범위를 left부터 right까지로 타이트하게 작성하여 문제를 해결하였다.

  • 정답을 저장하는 배열 answer를 선언한다.
  • left부터 right까지 반복하는 i에 대한 for문을 돌린다.
    -> answer에 max(divmod(i, n))+1의 값을 넣는다.
  • answer를 반환한다.

solution.py

def solution(n, left, right):
    answer=[]
    for i in range(left, right+1):
        answer.append(max(divmod(i, n))+1)
    return answer

profile
꾸준함을 꿈꾸는 SW 전공 학부생의 개발 일기

0개의 댓글