旋转数组 LeetCode(思维+模拟)

版权声明:欢迎转载,转载请注明原博客网址 https://blog.csdn.net/qq_37497322/article/details/82502380

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

示例 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) 的原地算法。

题解:

LeetCode基础题,暴力模拟也可以过,但是我觉得这题暴力过就失去了意义,做法有很多,下面是两种思路,经测试两种思路的时间复杂度都差不多都是O(1),而不是暴力模拟的k*O(1)

第一种:

将数组分为两部分,假设数组长度是n,第一组为[0,n-k-1],另外一组为[n-k,n-1],因为后面那组实际上是要平移到最前面,而前面那组是要平移到后面,即两组位置进行平移交换,那么我们可以经过三次翻转得到,第一次将第一组原地首尾互置,第二次将第二组原地首尾互置,最后将整个数组首尾互置,就得到了我们要的结果。

第二种:

假设数组长度为n,那么我们可以将数组分为n/k组,第一重循环遍历0到k-1,第二重循环通过数学推算出其他组相同位置的下标,比如n=6,1 2 3 4 5 6,k=2时,那么1 3 5就算作是每一组的相同位置,进行替换位移,最后每个元素遍历一次就可以完成换位,但是需要注意,当n/k不为整数时,需要将多出来的不成一组的位置进行特殊处理。。这部分还是很麻烦的,调了好几次才调好,代码也多了不少,最后击败了百分之99.97的人。。

本题需要注意的是数据贼坑,n,k都可以为0,k也可以大于n,需要特判和特殊处理。

我用的是第二种,代码:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if(nums.size()==0||k==0)
            return;
        k=k%nums.size();
        if(k==0)
            return;
        int s=nums.size();
        vector<int>tmp;
        int n=s/k;
        int p=k*(s/k);
        for(int i=0;i<k;i++)
        {
            int tmp1=nums[i];
            int tmp2;
            //printf("%d变为%d\n",nums[i],nums[(s-(k-i))%s]);
            nums[i]=nums[(s-(k-i))%s];
            for(int j=1;j<n;j++)
            {
                tmp2=nums[(i+j*k)%s];
                //printf("%d变为%d\n",nums[(i+j*k)%s],tmp);
                nums[(i+j*k)%s]=tmp1;
                tmp1=tmp2;
                if(i+(j+1)*k<s&&i+(j+1)*k>=p)
                {
                    tmp.push_back(tmp1);
                }
            }
            int j=0;
            if(i+(j+1)*k<s&&i+(j+1)*k>=p)
            {
                tmp.push_back(tmp1);
            }
        }
        if(s%k!=0)
        for(int i=0;i<tmp.size();i++)
        {
            nums[p+i]=tmp[i];
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_37497322/article/details/82502380