Taken from LeetCode. This is a moderatley difficult problem which gets harder if you stay within the rule of O(1) extra space.

The Question

Given an array, rotate the array to the right by k steps, where k is non-negative.

Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
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]

Do not return anything, modify nums in-place instead.

The Solution

The simplest, and completley valid, solution would be to use an additional array. By copying the values into a seperate array, you move the copied (and solved) array back to the original.

def rotate(self, nums: List[int], k: int) -> None:

    size = len(nums)
    copy = [0] * size

    for i, n in enumerate(nums):
        copy[( i + k ) % size] = n

    nums[:] = copy

Note nums[:] = copy. This is intentional, and it will not work as nums = copy as that will change the reference to a copy of nums and not use the original array.

The time complexity would be O(n) and the space complexity would be O(n), since you need an additional array.

The solution I (and many other people) came up with is to reverse the array.   After reversing the list, reverse the first k numbers. Then rotate the last n-k numbers. The first reverse puts the numbers in a more-or-less correct order, then the subsequent reverses solve the remainder.

def rotate(self, nums: List[int], k: int) -> None:

    n = len(nums)
    nums[:] = nums[n-(k % n):] + nums[:n-(k % n)]

The runtime complexity will still be O(n). This is still not O(1) complexity, since splicing and reversing the array will require extra space.