【LeetCode】【数组】189旋转数组 ————循环右移

  旋转数组

给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7]k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99]k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

旋转数组

数组法:
error: Line 23: index 11938 out of bounds for type 'int [100]'

//法1:少量数组法
//法1:少量数组交换法
//法1:少量数组法
void rotate(int* nums, int numsSize, int k) {
    
    int i=0;
    int temp[100];//临时存放
    
    k = k % numsSize; //右移最小次数
    
    /* 
     int rotate_dir = 1;//右移标志
    if(k>numsSize/2)
        rotate_dir = 0;//左移
    if(!rotate_dir) //左移
    {
        
        return ;
    }    
    */
    
    //默认右移
    //(0 ~ num-1-k) --> (k ~ num-1)
    //   
    for(i=numsSize-1;i>numsSize-1-k;i--)    //没有等于号 i>=numsSize-1-k
        temp[i+k-numsSize] = nums[i];   //保存被覆盖的数nums[i]
    for(i=numsSize-1; i>=k; i--)
        nums[i] = nums[i-k];            //nums[i]被覆盖,提前保存到temp中去, 再nums[i]=移位前一个数
    
    for(i = 0; i<=k-1; i++)         //赋值
        nums[i]=temp[i];
    
    
}

Rotate Array//法2:全部数组法
void rotate(int* nums, int numsSize, int k) {
    
    int i=0;
    int temp[100];//临时存放
    
    k = k % numsSize; //右移最小次数
    
    for(i=0;i<numsSize;i++)
        temp[(i+k)%numsSize] = nums[i];//创造一个一样大小的数组,全部赋值到temp中
    
    for(i=0;i<numsSize;i++)
        nums[i] = temp[i];      //再把temp复制给nums
    
    
}


//法3:只保留一个变量,逐个跳动法
void rotate(int* nums, int numsSize, int k) {
    
    int now = 0,start = 0, data_to_next = 0, temp = 0;
    int cnt = numsSize ;//用来表示跳转次数,次数到了,就停止循环
   
    k = k%numsSize;
    if(k==0)
        return;

    for(start = 0;start<numsSize;start++)
    {
        now = start;
        data_to_next =  nums[start%numsSize];   //第一个数,先提出来,用于 与下一个数交换
        while(1)
        {
            now = now+k;
        
            temp = nums[now%numsSize];           //交换一次       
            nums[now%numsSize] = data_to_next;
            data_to_next = temp;
            cnt--;      
            
            if((now%numsSize) == start)         //如果交换到start的开始,就结束本次跳转交换
                break;
                          
        }
   
        if(cnt==0)
            break;                
    }   


}



//法4:交换位置   逆序法

实现起来最简单!!!

Original List                   : 1 2 3 4 5 6 7
After reversing all numbers     : 7 6 5 4 3 2 1
After reversing first k numbers : 5 6 7 4 3 2 1
After revering last n-k numbers : 5 6 7 1 2 3 4 --> Result

//法4:调换位置,3次逆序法
void reverse(int *buf, int start, int end)
{
    int i=0;
    int temp=0;
    int cnt;
    cnt = (int)((end-start)/2+0.5);
    for(i=0;i<=cnt;i++)
    {
        temp = buf[start+i];
        buf[start+i]  = buf[end-i];
        buf[end-i] = temp;
    }
        
}

void rotate(int* nums, int numsSize, int k) {
/*
//测试reverse函数可以工作
    int i = 0;
    reverse(nums,0,numsSize-1);
    for(i = 0;i<numsSize;i++)
        printf("%d ",nums[i]);        
*/
    k = k%numsSize;
    if(k == 0 )
        return;
    reverse(nums,0,numsSize-1);
    reverse(nums,0,k-1);
    reverse(nums,k,numsSize-1);

}


猜你喜欢

转载自blog.csdn.net/qq1518572311/article/details/80302654
今日推荐