轮转数组(力扣)

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [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:

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

解答题目时,第一次看评论收到错误指示,以为下标只需要一个j=(j+i)%numsSize就可以解决问题,为了应用这个式子,开辟了一个新的数组(从这个时候就已经不符合题意了),新的数组长度未知,学习了定义未知长度的数组

int* num;

num = (int *)malloc(numsSize* sizeof(int));

得到的代码是:

void rotate(int* nums, int numsSize, int k){ 
 int i,j; 
 int* num;
 k=k%numsSize;
 num = (int *)malloc(numsSize* sizeof(int)); 
 for(i=0;i<numsSize;i++) {
 num[i]=nums[i];
 }
 for(i=0;i<numsSize;i++) {
 j=(i+k+1)%numsSize;
 nums[i]=num[j];
 } 
return nums[i];
}

能正确运行出给的例子答案,但是提交不成功,我才发现是应用的下标式子并不万能。

找思路的时候发现一个思路说,双层循环,外循环轮转次数,内循环先将末位拿出来,再向右移动一次,将末位放在首位。思路不错也好写。

void rotate(int* nums, int numsSize, int k){
 int i,temp,j;
 k=k%numsSize;
 for(i=0;i<k;i++) {
 temp=nums[numsSize-1]; 
 for(j=numsSize-1;j>0;j--) {
 nums[j]=nums[j-1]; 
 } 
nums[0]=temp; 
 }
}

能运行出来正确结果,但是提交显示超时。

另一个思路其实刚开始不想看,因为有点麻烦。它说将数组从(numsSize-k)处断开,前面一翻转后面一翻转,再将整体翻转。听起来很麻烦,实践了一下确实结果正确。它的简单之处在于写了一个翻转函数,直接调用了三次就能得到结果。(翻转函数我也不会写,刚开始想的是折半然后自己调用自己,后面发现原作者的思路很简单,就是从两头开始一对一对交换,low++,high--)

void rotate(int* nums, int numsSize, int k){
 k=k%numsSize; 
 reverse(nums,0,numsSize-k-1); 
 reverse(nums,numsSize-k,numsSize-1);
 reverse(nums,0,numsSize-1);
 }
 void reverse(int* a ,int low,int high){ 
  while(low<high){
  int temp=a[high];
  a[high]=a[low]; 
  a[low]=temp;
  low++; 
  high--; 
}
}

提交也没有问题,真厉害👍

———————————————————————————————————————————

class Solution {
    public void rotate(int[] nums, int k) {
        for(int i=0;i<k;i++){//进行k次一位轮转
           //进行一位轮转
            int l=0,r=nums.length-1;
            while(l<r){
            int q=nums[l];
            nums[l]=nums[r];
            nums[r]=q;
            l++;
                }
       }
    }
}

超时了!运行没有出错。

class Solution {
    public void rotate(int[] nums, int k) {
        k=k%nums.length;//如果k>nums.length,就进行取整,防止超出指针长度
        int L=0,R=nums.length-1;//现将数组进行翻转
        reserve(nums,L,R);   
         L=0;R=k-1;//再将前半段翻转
        reserve(nums,L,R);
         L=k;R=nums.length-1;//后半段翻转
        reserve(nums,L,R);
        

    }
    void reserve(int[] s,int x,int y){//翻转函数
        while(x<y){
            int q=s[x];
            s[x]=s[y];
            s[y]=q;
            x++;
            y--;
        }
        }
}

这个没有超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值