189.旋转数组,medium

第一次:
每次都向右平移一个,重复k次,结果超出时间限制
第二次:
想到了将k模sz(sz是数组长度)处理,然后循环替代前一个对应位置的元素,但是没有考虑到sz是k的倍数而导致一次循环并不能遍历所有元素这件事,提交运行错误
查看题解
法一是在另一新的数组中对应位置放置元素,虽然简单,确实我自己没有想到的。
法二,在原数组循环更新元素。也就是我的大体思路,官方解释数学推导挺复杂,但是在我自己的运行出错的基础上搞懂了大体含义
在这里插入图片描述
若从位置零开始,依次循环中2,4,6元素总是不会被访问到
这种情况总是sz是k的倍数,应该循环访问,每次循环的初始位置加一,直到初始位置为sz和k的最大公约数;

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        k = k % n;
        int count = gcd(k, n);//求最小公约数
        for (int start = 0; start < count; ++start) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % n;
                swap(nums[next], prev);//交换元素
                current = next;
            } while (start != current);
        }
    }
};

法三:三次数组翻转
k模sz处理后,向右平移k次即将尾部k个元素转移到数组首部,其余元素后移
评论中有个引用了美服的一个解释
nums = “----->–>”; k =3
result = “–>----->”;

reverse “----->–>” we can get “<–<-----”
reverse “<–” we can get “–><-----”
reverse “<-----” we can get “–>----->”
很形象

class Solution {
public:
    void reverse(vector<int>&nums,int n1,int n2){
        while(n1<n2){
            swap(nums[n1],nums[n2]);
            ++n1;
            --n2;
        }
    }
    void rotate(vector<int>& nums, int k) {
        k=k%(nums.size());
        reverse(nums,0,nums.size()-1);
        reverse(nums,0,k-1);
        reverse(nums,k,nums.size()-1);
    }
};

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值