简单易懂——轮转数组:将数组中的元素向右轮转 k 个位置(c语言实现LeeCode.189:中等)

在这篇博客文章中。

我们将讨论三种在C语言中将固定长度序列的数组,元素向右轮转'k'位的方法。

(即元素向右轮转' k' 个位置。如果元素挪动到了数组末尾,仍需要挪动,则从数组开头继续挪动)

我们这里使用动图来理解这个过程。

接下来所有的用例说明:将 后两个 数移动到整排数据的前面。即将数列右轮转‘2’位

方法一:翻转法

翻转法的时间复杂度为O(N),空间复杂度为O(1)。我们可以通过以下三个步骤实现:

  1. 翻转前半部分。
  2. 翻转后半部分。
  3. 翻转整体。 

步骤1和2:

简单易懂——轮转数组:将数组中的元素向右轮转 k 个位置(c语言实现LeeCode.189:中等)_第1张图片

步骤3:

简单易懂——轮转数组:将数组中的元素向右轮转 k 个位置(c语言实现LeeCode.189:中等)_第2张图片

代码部分:

void reverse(int* nums, int begin, int end) {
    while (begin < end) {
        int tmp = nums[begin];
        nums[begin] = nums[end];
        nums[end] = tmp;
        ++begin;
        --end;
    }
}

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

方法二:空间换时间法

空间换时间法的时间复杂度为O(N),空间复杂度为O(N)。我们可以通过将前后半段拷贝到一个新的数组中实现。

简单易懂——轮转数组:将数组中的元素向右轮转 k 个位置(c语言实现LeeCode.189:中等)_第3张图片

读懂代码,你可能需要的知识:

memcpy(需要数据的地址,源头地址,字节数)

指针的加减的具体含义

#粗略认识:待整理完相关资料将为大家设置超链接详解

方法二  代码详解:

void rotate(int* nums, int numsSize, int k) {
    if (k > numsSize) {
        k %= numsSize;
    }
    int* tmp = (int*) malloc(sizeof(int) * numsSize);
    memcpy(tmp, nums + numsSize - k, sizeof(int) * k);
    memcpy(tmp + k, nums, sizeof(int) * (numsSize - k));
    memcpy(nums, tmp, sizeof(int) * numsSize);
    free(tmp);
}

方法三:依次交换法——直觉算法(无法通过leecode测试!)

时间复杂度为 O(K*numSize) ≈ O(N^2)。应该尽量避免使用

简单易懂——轮转数组:将数组中的元素向右轮转 k 个位置(c语言实现LeeCode.189:中等)_第4张图片

具体代码实现:

void rotate(int* nums, int numsSize, int k) {
    if (k > numsSize) {
        k %= numsSize;
    }
    for (int i = 0; i < k; i++) {
        int last = nums[numsSize - 1];
        for (int j = numsSize - 1; j > 0; j--) {
            nums[j] = nums[j - 1];//相当于把‘K’之前的数,都往前挪动一位
        }
        nums[0] = last;
    }
}

现在我们已经提供了三种将数组中的前m个元素移动到数组末尾的方法。根据您的需求,您可以根据时间和空间复杂度选择合适的方法。

你可能感兴趣的:(C语言算法,c语言)