Javascript程序计算生成排序数组所需的旋转次数
给定一个数组 arr[] ,任务是找到将给定数组转换为排序形式所需的旋转次数。
例子:
Input: arr[] = {4, 5, 1, 2, 3}
Output: 2
Explanation:
Sorted array {1, 2, 3, 4, 5} after 2 anti-clockwise rotations.
Input: arr[] = {2, 1, 2, 2, 2}
Output: 1
Explanation:
Sorted array {1, 2, 2, 2, 2} after 1 anti-clockwise rotations.
天真的方法:
为了解决上面提到的问题,第一个观察是如果我们在数组中有n 个元素,那么在排序之后,最大的元素在第 (n – 1)个位置。在逆时针旋转 k 次后,最大元素将位于索引 (k – 1) 处(从开始的第 k个元素)。这里要注意的另一件事是,在旋转之后,最大元素的下一个元素将始终是最小元素,(除非最大元素在最后一个索引处,如果没有旋转则可能)。
因此,
Number of rotations (k) = index of smallest element (k) in the array
下面是上述方法的实现:
Javascript
Javascript
2
时间复杂度: O(N)
辅助空间: O(1)
有效的方法:
为了优化上述方法,我们将使用二分搜索。我们可以注意到,经过排序和旋转后,给定的数组被分成两半,其中的元素不递减,这是二分查找的唯一先决条件。在数组中执行递归二进制搜索以找到最小元素的索引。
下面是上述方法的实现:
Javascript
2
时间复杂度: O(N)
对于没有重复的数组,复杂度将为 O(logN)。但是如果数组包含重复项,那么它将递归调用对两半的搜索。所以最坏情况的复杂度将是 O(N)。
辅助空间: O(N)
在最坏的情况下,递归调用堆栈一次将有 N/2 个递归调用。
有关详细信息,请参阅有关生成排序数组所需的旋转计数的完整文章!