算法题13:轮转数组

题目描述:

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

 

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105

 

思路:

右移k个位置就是从最后一个元素删掉,然后再放到第一个元素的位置,当k超过数组长度时就可以把k%len(nums),即对数组长度相除取余,

比如题中示例数组长度为7,当k=8时,当k移到7时数组就还原了,其实就是移动了1次。

运行过程中发现不让直接赋值 nums = nums[-k:] + nums[:-k]),感觉这样更简单,非得一步一步调整nums才行。

但是切片这种方式会占用额空间,更合理的是后面的三步反转法。

python

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        if k > n:
            k = k % n
        # print("here nums[-k:] + nums[:-k]: ", nums[-k:] + nums[:-k])
        for i in range(k):
            temp = nums.pop()
            nums.insert(0, temp)

结果:

三次反转法:

 [1,2,3,4,5,6,7],  k = 3

把 [1,2,3,4,5,6,7]变成 [7,1,2,3,4,5,6],可以通过三步反转完成

第一步:把整个数据进行反转   

 [1,2,3,4,5,6,7] ==> [7,6,5,4,3,2,1]

第二步:反转前k个(3)

[7,6,5,4,3,2,1] ==> [5,6,7,4,3,2,1]

第三步:反转后n - k 个(4)

[5,6,7,4,3,2,1] ==> [5,6,7,1,2,3,4]

对于k >= n的情况,等同于反转k=k%n,即k对n相除取余的情况,因为对于k >= n的情况,由于轮转n次等同于没有轮转,轮转n + 1次等同于轮转1次,

所以依次类推,轮转k次就等同于轮转k对n相除取余次,即k mod n次。

 

python

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        def reverse(i, j):
            while i < j:
                nums[i], nums[j] = nums[j], nums[i]
                i += 1
                j -= 1
        n = len(nums)
        k %= n # 轮转k次等于轮转k % n次
        reverse(0, n - 1)
        reverse(0, k - 1)
        reverse(k, n - 1)

java:

 

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n; // 轮转k次等同于轮转k % n次
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }

    private void reverse(int[] nums, int i, int j) {
        while (i < j) {
            int temp = nums[i];
            nums[i++] = nums[j];
            nums[j--] = temp;
        }
    }
}

结果:

 

posted @ 2025-05-28 08:42  夏晓旭  阅读(37)  评论(0)    收藏  举报