【leetcode之189. 轮转数组】详解

【leetcode之189. 轮转数组】详解

  • 原题
  • 一、Create a new array
  • 二、Array flipping
  • 三.Ring substitution
  • 总结
    • 一天不力扣我就浑身难受。


原题

链接:https://leetcode.cn/problems/rotate-array/:

【leetcode之189. 轮转数组】详解_第1张图片
很有意思的一道题,本人提供三种方法,有更巧妙的方法的同学欢迎交流


正文开始

一、Create a new array

创建一个新数组,拿新数组进行(i+k)%numsize=i进行元素的偏移以达到题目目的,
再把新数组赋值给原先数组
图解:
【leetcode之189. 轮转数组】详解_第2张图片
【leetcode之189. 轮转数组】详解_第3张图片
代码实现:

void rotate(int* nums, int numsSize, int k){
  int num1[numsSize];
  for(int i=0;i<numsSize;i++)
  {
      num1[(i+k)%numsSize]=nums[i];
  }
  for(int i=0;i<numsSize;i++){
      nums[i]=num1[i];
  }
}

该方法时间复杂度为O(N),该方法创建了一个新数组,消耗内存,下面两种方法可以进一步优化

二、Array flipping

这个方法极奇难以想到,但是你见过一次就难以忘怀。
思路:

  1. 将整个数组翻转
  2. 将翻转后的数组从第0个到第k-1个翻转
  3. 将翻转后的数组从第k个到第numsize个翻转
    图解如下
    【leetcode之189. 轮转数组】详解_第4张图片
    【leetcode之189. 轮转数组】详解_第5张图片
    代码实现:
void swap(int* a, int* b) {
    int t = *a;
    *a = *b, *b = t;
}

void reverse(int* nums, int start, int end) {
    while (start < end) {
        swap(&nums[start], &nums[end]);
        start += 1;
        end -= 1;
    }
}

void rotate(int* nums, int numsSize, int k) {
    k %= numsSize;
    reverse(nums, 0, numsSize - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, numsSize - 1);
}

三.Ring substitution

解题技巧:

  • 我们可以把数组看成一个圆环,只要访问数组下标超过numsize就对numsize取余
  • 因为把一个元素i向后挪k个位置,那么第(i+k-1)个位置的元素势必被覆盖,故我们想到使用一个中间变量接收,然后再进行中间变量和第(i+k-1)进行交换,使中间变量不断后移。
  • 直到中间变量等与从开始的元素相等,第一次轮转结束
    图解:
    【leetcode之189. 轮转数组】详解_第6张图片
    【leetcode之189. 轮转数组】详解_第7张图片
    【leetcode之189. 轮转数组】详解_第8张图片
    得到结果
    代码实现:
void swap(int* a, int* b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}
void rotate(int* nums, int numsSize, int k)
{
    int cnt = 0;
    int temp, p;
    for (int start = 0; start < numsSize; start++)
    {
        temp = nums[start];
        p = start;
        do
        {
            p = (p + k) % numsSize;
            swap(&temp, &nums[p]);
            cnt++;
        } while (p != start);
        if (cnt == numsSize) break;
    }

}

执行结果:
【leetcode之189. 轮转数组】详解_第9张图片
该方法时间复杂度为O(1),内存消耗较小,效率较高

总结

第一种方法各位务必要掌握
第二种和第三种了解仅可

一天不力扣我就浑身难受。

                                      --莎士比亚

你可能感兴趣的:(LeetCode刷题之路,leetcode,算法,职场和发展)