leetcode 189. 轮转数组

231 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

轮转数组

189. 轮转数组 - 力扣(LeetCode) (leetcode-cn.com)

给你一个数组,将数组中的元素向右轮转 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 <= 10^5
  • -2^31 <= nums[i] <= 2^31 - 1
  • 0 <= k <= 10^5  

进阶:

  • 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

解题思路

通过取模运算完成数组逻辑上循环,将整个数组首尾相接,然后让每个元素向右跳k格,如果下一次的索引值超过了数组大小,由于取模运算索引值会落到数组大小范围之内。

运算步骤:

  1. 设置该轮首先要访问的索引值n,并与visited相比判断该索引值是否已经被访问。 注:visited是索引值,该索引值以及之后的索引值是一定会被访问的,所以visited一定是大于0且被访问的索引的最小值。

    在循环数组中,每个元素向前跳k格,有2种情况出现:

    • 第一种:每次跳k格,一轮过后,直接完成元素的轮转;
    • 第二种:每次跳k格,一轮过后,有剩余元素未能完成元素的轮转,需要进行第二轮,这个时候第二轮的选择依据便是上一次首存访问的索引值加1但是必须小于visited。
  2. 计算某元素需要移动到的下一个索引值(next_index + k) % nums.size(), 如果下一个索引值已经被访问,则退出改轮,再次判断这一轮结束后是否所有的元素已经被访问,即n是否仍比visited小。

  3. 判断这个索引值是否已经被访问过

    • 如果否,先判断,先保存该索引值的元素,然后用上一次的元素值覆盖。
    • 如果是,n++,跳到步骤1

代码实现

class Solution {
public:

    void rotate(vector<int>& nums, int k) {



        int n = 0;
        int visited = -1;

        while (visited == -1 || n < visited)
        {
            int temp;
            int temp2 = nums[n];
            int next_index = k + n;
            if (visited == -1 || next_index < visited)
            {
                visited = next_index % nums.size();
            }
            
            do
            {
                if (visited == -1 || (next_index % nums.size() < visited && next_index % nums.size() != n))
                {
                    visited = next_index % nums.size();
                }
                
                temp = nums[next_index % nums.size()];
                nums[next_index % nums.size()] = temp2;
                temp2 = temp;

                next_index+=k;
            }while (next_index % nums.size() != (k + n) % nums.size());

            n++;
        }
        


    

    }

};