LeetCode--Rotate Array(2重循环,n-1次swap)

关于循环移动,编程之美中曾提到一种手摇法,即需要三次循环,进行2n-3次swap,时间O(n),空间O(1),今天在这一题的Discuss上看到一个大神“3 lines of C++ in one pass using swap帖子,点了进去发现一个非常神奇算法,虽然是2重循环,但实际只有n-1次swap,这里将大神的英文帖子翻译一下:

原帖链接:https://oj.leetcode.com/discuss/26501/3-lines-of-c-in-one-pass-using-swap

void rotate(int nums[], int n, int k) {
    for (; k %= n; n -= k)
        for (int i = 0; i < k; i++)
            swap(*nums++, nums[n - k]);
}

每一次swap会将1个数调整好位置,所以总的运行时间是O(n)的,例如:

一开始,nums[] = [1,2,3,4,5,6,7], n = 7, k = 3

第1次外层循环之后,会得到nums[] 变为[4,1,2,3],n变为4,k变为3

第2次外层循环之后,nums[]变为[4],n变为1,k变为0

循环结束

这一模一减似乎做了很多事,不知道这是为什么,于是自己又举了个例子:

一开始nums[] = [1,2,3,4,5,6,7], n = 7, k = 5

第1次外层循环之后,会得到nums[]变为[3,4,5,6,7,2,1],n变为2,k变为1

第2次外层循环之后,会得到nums[]变为[3,4,5,6,7,1,2],n变为1,k变为0

循环结束

-------------------------------------------------------------------------------------- YY分割线 -----------------------------------------------------------------------------------------

感觉像减治法,但又说不上为什么,算法思想是找到当前位置应该是哪个数,即nums[n - k],然后进行交换,然后前k个数已经到位,还需要调整后面n-k个,为什么后面这n-k个数,又相当于是 k’ % n‘ 循环移位呢,YY一下,是不是因为这k个数swap到位时,最初的n-k个数调到了最后,并且做了k%(n-k)的循环移位,我们再对其进行k%(n-k)的循环移位实际上是将其相对位置进行恢复的操作,貌似有点意思,不过为什么最初的n-k个数做了k%(n-k)的循环移位呢,这是因为每一次swap,都将最前面的一个数调到了最后,呼呼,貌似YY的还有根有据的样子O(∩_∩)O~


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值