简体   繁体   中英

How can I improve my “rotate (roll / cyclic permutation) array” solution?

I am doing some stuff on leetcode and came up with solution it works fine but some cases. Here is the problem itself:

在此处输入图片说明

But in case like this it doesn't:

在此处输入图片说明

It doesn't make sense how can I rotate elements if k is bigger than length of array. If you have any idea how to improve this solution I would be grateful

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        if len(nums) > k:
            self.swap(nums, 0, len(nums)-1)
            self.swap(nums, 0,k-1)
            self.swap(nums, k, len(nums)-1)


    def swap(self, nums, start, end):

        while start < end:
            nums[start], nums[end] = nums[end], nums[start]
            start+=1
            end-=1

In order to understand why this doesn't work for the cases where k is larger than the array length, let me try to explain some of the logic behind rotating by such values of k .

The modulo operator, % will be useful. For example, if an array is 5 long, and you want to rotate by 5, you end up with the same array. So technically, you'd optimally want to rotate by 0. This is where the % operator comes into play. 5 % 5 = 0 . If we want to rotate an array length 5 by 7 spots, we would end up with the same thing as rotating the array by 2, and it turns out that 7 % 5 = 2 . Do you see where I am going with this?

This also holds true if the value of k is less than the length of the array. Say we want to rotate an array length 5 by 3, we do 3 % 5 = 3 .

So for any rotation of amount k and array length L , optimization rotation amount n is equivalent to n = k % L .

You should modify your code at the beginning of your rotate method to adjust the rotation amount:

k = k % L

and use this value to rotate the correct amount.

The fastest and cleanest solution by far and large is:

def rotate_right(items, shift):
    shift = -shift % len(items)
    return items[shift:] + items[:shift]


ll = [i + 1 for i in range(7)]
# [1, 2, 3, 4, 5, 6, 7]
rotate_right(ll, 3)
# [5, 6, 7, 1, 2, 3, 4]

rotate_right([1, 2], 3)
# [2, 1]

of course, short of using numpy.roll() or itertools.cycle() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM