NC110 旋转数组
NC110 旋转数组
描述
一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 $M$( $M>=0$)个位置,即将A中的数据由
$$
A_0 , A_1, \cdots , A_{N-1}
$$
变换为
$$
A_{N-M},\cdots,A_{N-1},A_0,A_1,\cdots ,A_{N-M-1}
$$
(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
数据范围:$0<n \leq 10$,$0 \leq m \leq 1000$
进阶:空间复杂度 $O(1)$,时间复杂度 $O(n)$
示例1
输入:
1 | 6,2,[1,2,3,4,5,6] |
返回值:
1 | [5,6,1,2,3,4] |
示例2
输入:
1 | 4,0,[1,2,3,4] |
返回值:
1 | [1,2,3,4] |
备注:
1 | (1<=N<=100,M>=0) |
我的题解
1 | import java.util.*; |
根据题目可以值n就是数组的长度,所以可以把上面的a.length替换成n:
1 | import java.util.*; |
大神题解
三次翻转
假设 n=7且 k=3
描述 | 数组状态 |
---|---|
原始数组 | 1 2 3 4 5 6 7 |
反转所有数字后 | 7 6 5 4 3 2 1 |
反转前 k=3 个数字后 | 5 6 7_4 3 2 1 |
反转后 n-k=4 个数字后 | 5 6 7_1 2 3 4 –> 结果 |
1 | import java.util.*; |
数组翻转
链接:https://www.nowcoder.com/questionTerminal/e19927a8fd5d477794dac67096862042?answerType=1&f=discussion
来源:牛客网
解题思路:
该方法基于如下的事实:将数组的元素向右移动 k 次后,尾部 m mod n 个元素会移动至数组头部,其余元素向后移动 m mod n 个位置。
该方法为数组的翻转:翻转算法参考 反转链表中的双指针方法 https://blog.nowcoder.net/n/d259b250747b4085bc7975f102d248c4
1、可以先将所有元素翻转,这样尾部的 m mod n 个元素就被移至数组头部,
2、然后再翻转 [0,m mod n−1] 区间的元素
3、 最后翻转[m mod n,n−1] 区间的元素即能得到最后的答案。
实例:
以 n=7,m=3 为例进行如下展示:
操作 | 结果 |
---|---|
原始数据 | 【1,2,3,4,5,6,7】 |
翻转所有元素 | 【7,6,5,4,3,2,1】 |
翻转 [0,m mod n −1] 区间的元素 | 【5,6,7,4,3,2,1】 |
翻转 [m mod n, n −1] 区间的元素 | 【5,6,7,1,2,3,4】 |
最后返回:【5,6,7,1,2,3,4】
复杂度分析
时间复杂度:O(N),其中 N 为数组的长度。每个元素被翻转两次,一共 N 个元素,因此总时间复杂度为 O(2N)=O(N)。
空间复杂度:O(1)。使用常数级空间变量