[189. Rotate Array] (알고리즘)
Array
문제
Given an integer array nums
, rotate the array to the right by k
steps, where k
is non-negative.
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3 Output: [5,6,7,1,2,3,4] Explanation: rotate 1 steps to the right: [7,1,2,3,4,5,6] rotate 2 steps to the right: [6,7,1,2,3,4,5] rotate 3 steps to the right: [5,6,7,1,2,3,4]
Example 2:
Input: nums = [-1,-100,3,99], k = 2 Output: [3,99,-1,-100] Explanation: rotate 1 steps to the right: [99,-1,-100,3] rotate 2 steps to the right: [3,99,-1,-100]
Constraints:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
Follow up:
- Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.
- Could you do it in-place with
O(1)
extra space?스스로 고민
접근법
- 배열 nums에 있는 숫자들을 k 횟수만큼 오른쪽으로 돌려준다.
- 예를 들어 1,2,3,4,5 가 있고 k 가 2면 - > 4,5,1,2,3
의사코드
- deque 을 사용해서 k 횟수만큼 앞에 있는걸 때서 뒤에 붙여준다.
- k 만큼 반복
구현 코드
from collections import deque
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
nums = deque(nums)
for _ in range(k):
x = nums.pop()
nums.appendleft(x)
- deque 을 사용하면 nums 자체를 관리하는게 아니라서 안된다.
- 직접 nums를 조작해야된다.
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
for _ in range(k):
x = nums.pop()
nums.insert(0, x)
시간 복잡도와 공간 복잡도
시간 복잡도
- 주어진 코드에서
pop()
과insert()
함수는 각각 O(1)의 시간 복잡도를 갖는다. 하지만 이들 함수들이k
번 반복되므로rotate
함수의 전체 시간 복잡도는 O(k * n)이 된다. 여기서n
은 리스트의 길이를 나타낸다. 따라서k
와n
이 모두 큰 값일 경우, 전체 시간 복잡도는 좋지 않다.
공간 복잡도
- 주어진 코드에서는 주어진 리스트
nums
를 직접 수정하므로, 추가적인 공간이 필요하지 않다. 따라서 공간 복잡도는 O(1) 다.
회고 과정
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k = k % n # To handle cases where k > n
# Reverse the entire list
def reverse(start, end):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
reverse(0, n - 1) # Reverse the entire list
reverse(0, k - 1) # Reverse the first k elements
reverse(k, n - 1) # Reverse the remaining elements
지금 코드에서 뭘 개선할 수 있지?
- 이렇게 하면 세 번의 리스트 반전만 하면 되서 시간 복잡도는 O(n) 으로 만들 수 있다.
- 단순히 구현만 생각했는데 공부할 수록 코드를 작성할 때 어떻게 구성하고 어떻게 작동될지를 염두하면서 작성해야 될 거 같다.
다른 사람 코드를 보고 그 기준으로 어떤 부분을 개선 할 수 있는지 최종 회고
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
temp = []
k = k % len(nums)
temp = nums[-k:]
nums[k:] = nums[:-k]
nums[:k] = temp
시간 복잡도
- 알고리즘은 세 번의 리스트 조작 연산을 수행한다.
temp = nums[-k:]
는 O(k),nums[k:] = nums[:-k]
역시 O(n), 그리고nums[:k] = temp
도 O(k)의 시간 복잡도를 갖는다. 총 시간 복잡도는 O(n + k)입니다. 하지만 일반적으로k
는n
보다 작으므로 이 알고리즘의 시간 복잡도는 O(n) 다.
공간 복잡도
- 알고리즘에서 사용되는 추가적인 공간은
temp
리스트 하나뿐이며, 이 리스트는 최대k
개의 원소를 저장한다. 따라서 공간 복잡도는 O(k) 다.
댓글남기기