본문 바로가기
코딩테스트/코딩테스트 문제

코딩테스트 준비 - 프로그래머스: 행렬 테두리 회전하기 풀이(파이썬)

by 공부가싫다가도좋아 2021. 6. 30.
반응형

프로그래머스: 행렬 테두리 회전하기 풀이


문제풀러가기

https://programmers.co.kr/learn/courses/30/lessons/77485?language=python3 

 

코딩테스트 연습 - 행렬 테두리 회전하기

6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]

programmers.co.kr


문제 분석

1. 행과 열에 관한 문제는 대부분 좌표를 사용하여 푼다.

2. queries = [2,2,5,4]일 경우, 사각형의 좌표는 (1,1) (1,3) (4,1) (4,3)


코드

from collections import deque
def solution(rows, columns, queries):
    cnt=1
    result=[]
    for i in range(rows):
        a=[]
        for j in range(columns):
            a.append(cnt)
            cnt+=1
        result.append(a)
    
    arr_min=[]
    for c in range(len(queries)):
        i=queries[c][0]-1
        j=queries[c][1]-1
        queue=deque()
        while True:
            if len(queue)==0:
                queue.append(result[i][j])
                min=result[i][j]
            else:
                queue.append(result[i][j])
                if min>result[i][j]:
                    min=result[i][j]
                result[i][j]=queue.popleft()
                
            if i==queries[c][0]-1 and j<queries[c][3]-1:
                j+=1
            elif i<queries[c][2]-1 and j==queries[c][3]-1:
                i+=1
            elif i==queries[c][2]-1 and j>queries[c][1]-1:
                j-=1
            elif i>queries[c][0]-1 and j==queries[c][1]-1:
                i-=1
            if (i==queries[c][0]-1) and (j==queries[c][1]-1):
                break

        result[i][j]=queue.popleft()

        arr_min.append(min) 
    return arr_min

코드 풀이

위 코드를 한 단락씩 끊어서 설명하겠습니다.

 

rows = 6, columns=6, queries = [2,2,5,4] 일 경우

from collections import deque
def solution(rows, columns, queries):
    cnt=1
    result=[]
    for i in range(rows):
        a=[]
        for j in range(columns):
            a.append(cnt)
            cnt+=1
        result.append(a)
    
  • 위 코드를 돌리면
  • [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18], [19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36]] 이런 배열이 생깁니다.
  • 보기 쉽게 도식화하면 아래 그림과 같은 모양이 생깁니다.

 

 

    arr_min=[]
    for c in range(len(queries)):#[[2,2,5,4]]
        i=queries[c][0]-1
        j=queries[c][1]-1
        queue=deque()
  • queries=[[2, 2, 5, 4]] 일 때, 좌표(1,1) 부터, 숫자를 오른쪽으로 한칸씩 옮겨야 되므로,
  • 초기 i,j는 시작점인 queries[c][0]-1, queries[c][1]-1로 설정해줍니다.
  • 그리고, 한칸씩 옮길때마다 deque에 값을 넣어 줄 것이므로 deque을 생성합니다.

 

 

        while True:
            if len(queue)==0:
                queue.append(result[i][j])
                min=result[i][j]
            else:
                queue.append(result[i][j])
                if min>result[i][j]:
                    min=result[i][j]
                result[i][j]=queue.popleft()
                

 

  • while True문으로 작업을 계속 반복 수행할 수 있도록 합니다.
  • deque에 아무 요소가 없을때, deque과 min변수에 초기값 을 넣어 줍니다. 위에서 i= queries[c][0]-1,j= queries[c][1]-1 로, 초기값 result[i][j]=result[1][1]=8을 deque과 min에 넣습니다. 
  • 아래 if문을 돌린 후, deque에 요소가 생겼을 때, 현재 위치에 있는 값을 deque에 넣고, deque에 있는 값을 popleft를 통해, 현재위치에 대입합니다.
  • 또한 값을 대입하기전, min변수를 통해, min에 있는 변수보다 현재 값이 더 작으면 min에 대입, 아니면 패쓰합니다.

 

 

            if i==queries[c][0]-1 and j<queries[c][3]-1:
                j+=1
            elif i<queries[c][2]-1 and j==queries[c][3]-1:
                i+=1
            elif i==queries[c][2]-1 and j>queries[c][1]-1:
                j-=1
            elif i>queries[c][0]-1 and j==queries[c][1]-1:
                i-=1
            if (i==queries[c][0]-1) and (j==queries[c][1]-1):
                break

이제 오른쪽으로 한바퀴 회전하기 위한 if문을 만들어 줍니다. 

*queries=[[2,2,5,4]]

  • 처음 if문에서,  i = queries[c][0]-1 = 1, j = queries[c][1]-1 = 1 부터 오른쪽으로 한칸씩 이동하기 위해 i는 그대로 1을 유지하며,  j = 3이 될 때까지, j+=1을 해줍니다.
  • 두번째 elif문에서, 아래로 한칸씩 이동하기 위해, j=3을 유지하며,  i = queries[c][2]-1 = 4가 될 때까지 i+=1을 해줍니다.
  • 세 번째 elif 문에서, 왼쪽으로 한 칸씩 이동하기 위해, i=4를 유지하며,  j=queries[c][1]-1 = 1이 될 때까지 j-=1을 해줍니다.
  • 네 번째 elif문에서 , 위로 한 칸씩 이동하기 위해, j=1을 유지하며, i=queries[c][0]-1=1이 될 때까지 i-=1을 해줍니다.
  • 마지막 else문은 다시 i와 j가 처음 시작 지점 (1,1)로 돌아왔을때 break를 통해 while문을 멈춘다.

 

        result[i][j]=queue.popleft()

        arr_min.append(min) 
    return arr_min
  • 첫 번째 for문이 끝날때 마다, 마지막 위치에 있는, 즉 14 (좌표번호(2,1)위치에 있는 값)값을, 맨 처음 시작 위치에 넣어줘야 하므로, result[i][j]에 deque에 있는 요소를 넣어준다.
  • 그리고 min값을 arr_min 리스트에 넣어준다.

 

반응형

댓글