简答(python 代码)
def reverse(arr, i, j):
for idx in xrange((j - i + 1) / 2):
arr[i+idx], arr[j-idx] = arr[j-idx], arr[i+idx]
def solution(A, K):
l = len(A)
if l == 0:
return []
K = K%l
reverse(A, l - K, l -1)
reverse(A, 0, l - K -1)
reverse(A, 0, l - 1)
return A
长答案(代码说明)
让我先谈谈K < N的基本情况,这种情况下的想法是将数组分成两部分A和B,A是第一个N-K元素数组和@987654335 @ 最后一个 K 元素。算法分别反转A和B,最后反转整个数组(两部分分别反转)。要使用K > N 管理这种情况,请认为每次反转数组N 时都会再次获得原始数组,因此我们可以使用模块运算符找到拆分数组的位置(仅反转真正有用的时间避免无用的转移)。
图形分步示例有助于更好地理解概念。请注意
- 粗线表示数组的分割点(本例中K=3);
- 两个红色数组分别表示输入和预期输出。
起点:
看看我们想要在最终输出前面的最后 3 个字母反转,现在让它反转(算法的第一个反转):
现在反转前 N-K 个元素(算法的第二个反转):
我们已经有了解决方案,但是在相反的方向上,我们可以通过反转整个数组来解决它(算法的第三个也是最后一个反转):
这里是最终输出,原始数组循环旋转K = 3。
让我们再给出一个使用python代码的逐步示例,从:
A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
K = 22
N = len(A)
我们找到分裂索引:
K = K%N
#2
因为,在这种情况下,前 20 个移位将没有用,现在我们将原始数组的最后一个 K (2) 个元素反转:
reverse(A, N-K, N-1)
# [1, 2, 3, 4, 5, 6, 7, 8, 10, 9]
如您所见,9 和 10 已经移位,现在我们反转前 N-K 个元素:
reverse(A, 0, N-K-1)
# [8, 7, 6, 5, 4, 3, 2, 1, 10, 9]
最后,我们反转整个数组:
reverse(A, 0, N-1)
# [9, 10, 1, 2, 3, 4, 5, 6, 7, 8]
请注意,反转数组的时间复杂度为 O(N)。