只需迭代数组,找到第一个索引i,使得arr[i] > arr[i+1](如果没有这样的索引,我们就完成了,因为数组已经排序了),然后检查arr[i+1],...,arr[n]是否排序,如果@ 987654324@。如果是,可以通过 n-i 旋转来完成。
否则,没有办法。
时间复杂度为 O(n),空间复杂度为 O(1)。
附录:算法的正确性:
权利要求 1:
如果数组不能拆分成两个数组
arr[1],arr[2],..,arr[i] 和 arr[i+1],...,arr[n] - 均已排序,
那就没有办法了。
证明:
让我们假设i 是arr[i] > arr[i+1] 所在的第一个索引,并让j 是其他一些索引,例如arr[j] > arr[j+1], j!=i。一定有这样的,因为arr[i+1],...,arr[n] 是未排序的。
根据定义,虽然j+1 不是“单位移位”,但数组是未排序的。
刚移位后,由于arr[i] > arr[i+1]仍然没有排序,又一次移位后,arr[j]又在arr[j+1]之前,违反了排序顺序。
因此,数组无法排序。
权利要求 2:
假设一个数组可以拆分为两个有序数组
arr[1],...,arr[i] 和 arr[i+1],...,arr[n]。
还假设
arr[i] > arr[i+1]。
然后,数组可以“单位移位”成
排序一,当且仅当arr[n] <= arr[1]。
证明:
<---
数组未排序,因此至少要进行一次单位移位。这个单位移位将arr[n]放在arr[1]之前,除非arr[n]<=arr[1],否则数组永远不会被排序
--->
假设arr[n]<=arr[1],那么通过移动arr[i+1],...,arr[n],我们得到以下数组:
arr[i+1],arr[i+2],...,arr[n],arr[1],arr[2],...,arr[i]
请注意arr[i+1]<= arr[i+2] <= .... <= arr[n],因为我们假设它已排序。
同样arr[1]<=arr[2]<=...<=arr[i]
另请注意arr[n] <= arr[i],来自假设。
通过加入上述 3 个不等式,我们得到:
arr[i+1] <= arr[i+2] <= ... <= arr[n] M= arr[1] <= arr[2] <= ... <= arr[i]
根据定义,上面是一个排序数组,它结束了声明的证明。
权利要求 3:
算法正确
通过应用 claim1、claim2 并专门处理数组已经排序的情况,我们得到:
当且仅当以下情况下,可以使用“单位移位”对数组进行排序:它已经排序,或者声明 2 的条件适用,并且证明结束。
QED