Language/Python
[Python] 2차원 배열 회전 : zip( ), 인덱스를 고려한 회전
위시리
2024. 10. 10. 14:46
1. zip( ) 활용
정사각형, 직사각형 모두 적용 가능하다.
- 시계 방향 90 ( = 반시계방향 270 )
arr = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
arr90 = list(map(list, zip(*arr[::-1])))
print(arr90)
# [[9, 5, 1], [10, 6, 2], [11, 7, 3], [12, 8, 4]]
- 시계 방향 180 ( = 반시계 방향 180 )
arr = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
arr180 = [a[::-1] for a in arr[::-1]]
print(arr180)
# [[12, 11, 10, 9], [8, 7, 6, 5], [4, 3, 2, 1]]
- 시계 방향 270 ( = 반시계 방향 90 )
arr = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
arr270 = [x[::-1] for x in list(map(list, zip(*arr[::-1])))[::-1]]
print(arr270)
# [[4, 8, 12], [3, 7, 11], [2, 6, 10], [1, 5, 9]]
- 외우고 있다면 빠르게 구현 가능
- 장점 : 정사각형, 직사각형 둘 다 적용 가능하고, 배열의 인덱스 고민없이 빠르게 처리할 수 있다.
- 단점 : 메모리나 시간 복잡도 면에서는 인덱스 규칙을 찾아서 회전하는 것보다 좋지 않다.
2. 인덱스 규칙 찾아서 회전
정사각형
- 시계 방향 90 ( = 반시계 방향 270 )
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = 3
new90 = [[0] * n for _ in range(n)]
for i in range(n) :
for j in range(n) :
new90[j][n-i-1] = arr[i][j]
print(new90)
# [[7, 4, 1], [8, 5, 2], [9, 6, 3]]
- 시계 방향 180 ( = 반시계 방향 180 )
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = 3
new180 = [[0] * n for _ in range(n)]
for i in range(n) :
for j in range(n) :
new180[n-j-1][n-i-1] = arr[i][j]
print(new180)
# [[9, 6, 3], [8, 5, 2], [7, 4, 1]]
- 시계 방향 270 ( = 반시계 방향 90 )
arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = 3
new270 = [[0] * n for _ in range(n)]
for i in range(n) :
for j in range(n) :
new270[n-j-1][i] = arr[i][j]
print(new270)
# [[3, 6, 9], [2, 5, 8], [1, 4, 7]]
직사각형
- 시계 방향 90 ( = 반시계 방향 270 )
def rotated_90(a) :
w = len(a) # 세로 길이 -> 가로
h = len(a[0]) # 가로 길이 -> 세로
result = [[0] * w for _ in range(h)]
for i in range(w) : # 원래 배열 a는 w가 세로였기 때문에 w를 먼저 돌아야 한다.
for j in range(h) :
result[j][w-i-1] = a[i][j]
return result
a = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
print(rotated_90(a))
# [[9, 5, 1], [10, 6, 2], [11, 7, 3], [12, 8, 4]]
N | Before | After |
1 | (0, 0) | (0,2) |
2 | (0, 1) | (1,2) |
3 | (0, 2) | (2,2) |
4 | (0, 3) | (3,2) |
- 기존의 i 행은 [ h - 1 + i ] 열로 이동
- 기존의 j 열은 로 이동 새로운 행 j 로 이동
- 시계 방향 180 ( = 반시계 방향 180 )
def rotated_180(a) :
m = len(a) # 세로 길이 -> 가로
n = len(a[0]) # 가로 길이 -> 세로
result = [[0] * m for _ in range(n)]
for i in range(m) :
for j in range (n) :
result[n-j-1][m-i-1] = a[i][j]
return result
a = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
print(rotated_180(a))
# [[12, 8, 4], [11, 7, 3], [10, 6, 2], [9, 5, 1]]
- 시계 방향 270 ( = 반시계 방향 90 )
def rotated_270(a) :
m = len(a) # 세로 길이 -> 가로
n = len(a[0]) # 가로 길이 -> 세로
result = [[0] * m for _ in range(n)]
for i in range(m) :
for j in range (n) :
result[n-j-1][i] = a[i][j]
return result
a = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
print(rotated_270(a))
# [[4, 8, 12], [3, 7, 11], [2, 6, 10], [1, 5, 9]]
3. 부분 회전
2차원 배열의 특정 부분만 회전시키는 것
7x7 배열 arr의 일부 영역을 시계방향으로 90도 회전
arr = [[7 * j + i for i in range(1,8)] for j in range(7)]
new_arr = [[0] * 7 for _ in range(7)]
print('원본 : ')
for i in range(len(arr)) :
print(arr[i])
sh, sw = 2,2 # 시작점 인덱스
length = 3 # 회전시킬 정사각형의 한 변의 길이
# 배열의 특정 부분 회전
def ro90(sh, sw, length) :
global arr, new_arr
# 정사각형 90도 회전
for h in range(sh, sh + length) :
for w in range(sw, sw + length) :
# 1. (2,2) 지점에서 각 좌표를 (0,0) 기준으로 변환
# 정사각형의 영역의 원점에서 얼마나 떨어져 있는지 계산
oh, ow = h - sh, w - sw
# 2. 90도 회전한 좌표 계산
rh, rw = ow, length - oh - 1
# 3. 회전 좌표에 맞게 new_arr에 값 복사 : 다시 (sh,sw)를 더해줌
new_arr[sh + rh][sw + rw] = arr[h][w]
# new_arr 의 값을 원본 배열 arr에 반영
for h in range(sh, sh + length) :
for w in range(sw, sw + length) :
arr[h][w] = new_arr[h][w]
# print(arr[h][w])
ro90(sh, sw, length)
print('시계 방향 90 회전 : ')
for i in range(len(arr)) :
print(arr[i])
결과
REFERENCE
SW 역량 테스트 치르기 전 숙지하면 좋을 삼성 빈출 코드 유형 정리 🕵🏼♀️🌀🦈
삼성 기출에서 자주 나오는 코드 유형들을 추려봤습니다 혹시 자주 나오는 또다른 유형이 있다면 댓글로 알려주시면 감사하겠습니다 🙇🏻♀️
velog.io
[Python] 2차원 배열 회전 알고리즘 ( 프로그래머스 : 자물쇠와 열쇠 )
행과 열의 수가 같은 정방형 배열(square array 또는 square matrix) 에서 2차원 배열을 오른쪽으로 90도 회전 시키는 방법에 대해 알아보자.
velog.io