轮转数组的含义:
所谓轮转就是像轮子一样转,我们把数组比作是一条车链,把数组1,2,3,4,5,6,7向右边移动,后面的7会轮转到最开始的1的位置,如此循环,比如数组向右移动1位数组就是7 ,1,2,3,4,5,6.
轮转数组的实现:
要实现转轮数组,不得不的提一下三段置换,它是一种数学方法,在程序设计中广泛用于字符逆序,字符左旋右旋等地方,使用方法就是先把你需要移动的部分使用逆序函数逆序,这是第一次,再把数组的另一部分逆序,这是第二次,最后把整个数组逆序,此时就可以发现整个数组可以实现轮转,这是一个数学方法,一般是很难想出来的,我们只管应用,其原理不需要深究。
轮转数组的实践:
题目:
给定一个正数数组nums,将数组的元素向右轮转K个位置,其中k是非负数。——题目来源leetcode可以搜轮转数组
方法一:
三段置换:
//逆序函数
void reverse(int *a,int left,int right)
{
while(left<right)
{
int tmp = a[left];
a[left] = a[right];
a[right] = tmp;
left++;
right--;
}
}
//逆序三次
void rotate(int* nums, int numsSize, int k) {
k %= numsSize;//k可能大于数组个数,当等于数组个数时就是一轮,比数组个数大1时就是轮转一次
reverse(nums,0,numsSize-k-1);//数组起始地址 ,左下标和右下标,注意k是数组右端的个数不是左端
reverse(nums,numsSize-k,numsSize-1);
reverse(nums,0,numsSize-1);
}
方法二:
直接分段复制到临时数组,用空间换时间
void rotate(int* nums, int numsSize, int k) {
k %= numsSize;
int* NewArr = (int*)malloc(sizeof(int)*numsSize);//开辟新空间
if(NewArr==NULL)
{
perror("malloc");
}
memcpy(NewArr,nums+numsSize-k,k*sizeof(int));//把后段复制到临时数组
memcpy(NewArr+k,nums,sizeof(int)*(numsSize-k));//把前段复制到临时数组
memcpy(nums,NewArr,sizeof(int)*numsSize);//从临时数组复制回去原数组
free(NewArr);
NewArr =NULL;
}
总结:三段置换应用再逆序和旋转的领域十分有用,逆序逆序再逆序,十分简单好用,在遇到数组有关旋转的地方可以多多注意使用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。