轮转数组的含义:

所谓轮转就是像轮子一样转,我们把数组比作是一条车链,把数组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;
}

总结:三段置换应用再逆序和旋转的领域十分有用,逆序逆序再逆序,十分简单好用,在遇到数组有关旋转的地方可以多多注意使用。


Hhh_灏
24 声望3 粉丝