midjourney prompt:One afternoon, the warm sun shines through the shade of a young girl with white skin. The girl blushed slightly and looked at me with a smile. Detailed anime style with coordinated proportions.
在这篇博客文章中
我们将讨论三种在C语言中将固定长度序列的数组,元素向右移动'k'位的方法。
(即元素向右轮转' k' 个位置。 如果元素挪动到了数组末尾,仍需要挪动,则从数组开头继续挪动)
我们这里使用动图来理解这个过程。
接下来所有的用例说明:将 后两个 数移动到整排数据的前面。即将数列右轮转‘2’位。
(似乎也有“右旋”一说)
方法一:翻转法
翻转法的时间复杂度为O(N),空间复杂度为O(1)。我们可以通过以下三个步骤实现:
1.翻转前半部分。
2.翻转后半部分。
3.翻转整体。
步骤1和2:
步骤3:
代码部分:
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)。我们可以通过将前后半段拷贝到一个新的数组中实现。
读懂代码,你可能需要的知识:
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)。应该尽量避免使用
具体代码实现:
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;
}
}