Data Structures and Algorithms/Leetcode
[30일 챌린지] 문자열 옮기기 (Perform String Shifts)
Jay김
2020. 4. 15. 07:59
목표
당신에게 소문자 영단어가 들어가 있는 문자열(string) 's'와 행렬(matrix) 'shift'가 주어질 것이다. 다르게 보면 리스트로 이루어진 리스트인 'shift'의 내용물은 다음과 같다.
shift [i] = [방향, 칸 수]
방향 값은 0 혹은 1이다. 0은 왼쪽 1은 오른쪽이다.
칸 수 값은 해당 방향으로 몇 칸 옮겨야 (shift) 하는지 가리킨다.
주어진 입력값에 따라 출력값을 내는 함수를 정의하라.
예시 1
입력값: s = "abc", shift = [[0,1], [1,2], [0,3]]
출력값: "cab"
해설: [0,1] 은 왼쪽으로 1칸 이동을 명령한다. "abc" → "bca"
[1,2] 은 오른쪽으로 2칸 이동을 명령한다. "bca" → "cab"
[0,3] 은 왼쪽으로 3칸 이동을 명령한다. "cab" → "cab"
답 1
바로 파이썬의 인덱스 슬라이싱이 생각날 것이다. 문자열 자체의 내용물을 바꾸는 것이 아니라 문자열을 변경시킨 카피를 만들고 문자열의 주소를 가리키는 변수 s를 변경시키는 것이기 때문에 변경 불가 개체 에러가 날 염려는 없다.
알고리즘은 다음과 같다.
- shift 행렬을 for 루프로 읽는다.
- shift 행렬에 들어있는 리스트의 인덱스 0을 확인해 방향 값을 읽는다. 이때 if 문으로 0 혹은 1에 따라 실행할 작업을 나눠준다.
- 문자를 이동한 수에서부터 인덱스 슬라이싱을 하여 서브 문자열을 만들고 거기에 나머지 문자열 내용이 들어있는 서브 문자열을 더해준다. 예를 들어 "abc"에 [0,1] 작업을 실행한다면 "bca"가 된다. 이는 곧 리스트를 인덱스 1부터 인덱스 2까지 읽은 뒤 다시 인덱스 0부터 시작하는 것과 동일한 작업이 된다. 그러니까 s [1:]+s [:1] = "bc" + "a" = "bca"로 같은 결과물에 도달할 수 있다. 오른쪽으로 이동하는 [1,1] 작업을 실행한다면 s [-1:] + s [:-1]를 실행하면 된다. 인덱스 -1 은 곧 끝의 인덱스와 동일하다. 즉, "c" + "ab" = "cab"라는 결과물에 도달할 수 있다.
- 이 결과물을 다시 s에 다시 지정(assign)해준다.
1
2
3
4
5
6
7
8
|
def stringShift(s, shift):
for i in shift:
if i[0] == 0:
s = s[i[1]:]+s[:i[1]]
else:
s = s[-i[1]:]+s[:-i[1]]
return s
|
cs |
답 2
즉시 shift에서 값을 선언하고 사용하는 방법이다. 살짝 더 빠르다.
1
2
3
4
5
6
7
8
|
def stringShift(s, shift):
for 방향, 칸수 in shift:
if 방향 == 0:
s = s[칸수:]+s[:칸수]
else:
s = s[-칸수:]+s[:-칸수]
return s
|
cs |
추가 답
살짝 더 빠르게 만들고자 한다면 같은 왼쪽 칸 수 이동과 오른쪽 칸 수 이동이 곧 제자리라는 사실을 이용하자.
[Copyright ⓒ 블로그채널 무단전재 및 재배포 금지]