当前位置 博文首页 > HJY:旋转数组 LeetCode(思维+模拟)

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

    作者:[db:作者] 时间:2021-09-22 16:59

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

    示例 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];
            }
        }
    };

    ?

    cs
    下一篇:没有了