C++程序 找出经过若干次旋转后给定索引处的元素
给定一个由N个整数组成的数组,我们可以进行[L..R]范围内的若干次右循环旋转。在进行这些旋转后,我们需要找到给定索引处的元素。
例如:
方法:暴力法 暴力法的方法是将所有给定范围的数组都旋转一遍,最后返回修改后数组中给定索引处的元素。
方法:高效法 我们可以保存所有的旋转范围,并进行离线处理。
假设,我们的旋转范围是:[0..2]和[0..3]
我们从后往前遍历这些范围。
在范围[0..3]之后,索引0会有索引3的元素。
因此,我们可以将0更改为3,即如果索引=left,则索引将更改为right。
在范围[0..2]之后,索引3将保持不变。
因此,我们可以做出3种情况:
如果索引=left,则索引将更改为right。
如果索引不受范围约束,则旋转无效果。
如果索引位于范围内,则索引将具有索引-1处的元素。
下面是实现细节:
更好的解释:
10 20 30 40 50
索引:1
旋转范围:{0,2} {1,4} {0,3}
答案:在顺序{0,2} {1,4} {0,3}下,索引1将拥有30的所有3个旋转后。
我们对A执行{0,2},现在我们有一个新的数组A1。
我们对A1执行{1,4},现在我们有一个新的数组A2。
我们对A2执行{0,3},现在我们有一个新的数组A3。
现在,我们正在A3中查找索引1处的值。
但是A3是在A2上进行{0,3}操作得到的。
因此,A3中的索引1是A2中的索引0。
但是A2是在A1上进行{1,4}操作得到的。
因此,A2中的索引0也是A1中的索引0,因为它不在范围{1,4}内。
但是A1是在A上进行{0,2}操作得到的。
因此,A1中的索引0是A中的索引2。
注意,我们按逆序处理旋转范围而不是按逆序旋转元素,只是从后往前处理索引。
因为如果我们实际上按逆序旋转,则可能会得到完全不同的答案,在旋转中顺序是重要的。
输出:
时间复杂度: O(N),其中N代表给定旋转次数。
辅助空间: O(1),不需要额外的空间,因此是一个常数。