给定一个数组 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
下面是上述方法的实现:
C++
// C++ program to find the
// count of rotations
#include
using namespace std;
// Function to return the count
// of rotations
int countRotation(int arr[], int n)
{
for(int i = 1; i < n; i++)
{
// Find the smallest element
if (arr[i] < arr[i - 1])
{
// Return its index
return i;
}
}
// If array is not
// rotated at all
return 0;
}
// Driver Code
int main()
{
int arr1[] = { 4, 5, 1, 2, 3 };
int n = sizeof(arr1) / sizeof(int);
cout << countRotation(arr1, n);
}
// This code is contributed by jrishabh99
Java
// Java Program to find the
// count of rotations
public class GFG {
// Function to return the count of
// rotations
public static int countRotation(int[] arr,
int n)
{
for (int i = 1; i < n; i++) {
// Find the smallest element
if (arr[i] < arr[i - 1]) {
// Return its index
return i;
}
}
// If array is not
// rotated at all
return 0;
}
// Driver Code
public static void main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
System.out.println(
countRotation(
arr1,
arr1.length));
}
}
Python3
# Python3 program to find the
# count of rotations
# Function to return the count
# of rotations
def countRotation(arr, n):
for i in range (1, n):
# Find the smallest element
if (arr[i] < arr[i - 1]):
# Return its index
return i
# If array is not
# rotated at all
return 0
# Driver Code
if __name__ == "__main__":
arr1 = [ 4, 5, 1, 2, 3 ]
n = len(arr1)
print(countRotation(arr1, n))
# This code is contributed by chitranayal
C#
// C# program to find the count of rotations
using System;
class GFG{
// Function to return the count of
// rotations
public static int countRotation(int[] arr,
int n)
{
for(int i = 1; i < n; i++)
{
// Find the smallest element
if (arr[i] < arr[i - 1])
{
// Return its index
return i;
}
}
// If array is not
// rotated at all
return 0;
}
// Driver Code
public static void Main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
Console.WriteLine(countRotation(arr1,
arr1.Length));
}
}
// This code is contributed by gauravrajput1
Javascript
C++
// C++ program to implement the
// above approach
#include
using namespace std;
// Function to return the
// count of rotations
int countRotation(int arr[], int low,
int high)
{
// If array is not rotated
if (low > high)
{
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high && arr[mid] > arr[mid + 1])
{
// The next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low && arr[mid] < arr[mid - 1])
{
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low])
{
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr, mid + 1,
high);
}
if (arr[mid] < arr[high])
{
// Smallest element lies on the
// left subarray
return countRotation(arr, low,
mid - 1);
}
else
{
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr, low,
mid - 1);
if (rightIndex == 0)
{
return leftIndex;
}
return rightIndex;
}
}
// Driver code
int main()
{
int arr1[] = { 4, 5, 1, 2, 3 };
int N = sizeof(arr1) / sizeof(arr1[0]);
cout << countRotation(arr1, 0, N - 1);
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java Program to implement
// the above approach
public class GFG {
// Function to return the
// count of rotations
public static int countRotation(int[] arr,
int low,
int high)
{
// If array is not rotated
if (low > high) {
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high
&& arr[mid] > arr[mid + 1]) {
// the next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low
&& arr[mid] < arr[mid - 1]) {
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low]) {
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr,
mid + 1,
high);
}
if (arr[mid] < arr[high]) {
// Smallest element lies on the
// left subarray
return countRotation(arr,
low,
mid - 1);
}
else {
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr,
low,
mid - 1);
if (rightIndex == 0) {
return leftIndex;
}
return rightIndex;
}
}
// Driver Program
public static void main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
System.out.println(
countRotation(
arr1,
0, arr1.length
- 1));
}
}
Python3
# Python3 program to implement the
# above approach
# Function to return the
# count of rotations
def countRotation(arr, low, high):
# If array is not rotated
if (low > high):
return 0
mid = low + (high - low) // 2
# Check if current element is
# greater than the next
# element
if (mid < high and arr[mid] > arr[mid + 1]):
# The next element is
# the smallest
return mid + 1
# Check if current element is
# smaller than it's previous
# element
if (mid > low and arr[mid] < arr[mid - 1]):
# Current element is
# the smallest
return mid
# Check if current element is
# greater than lower bound
if (arr[mid] > arr[low]):
# The sequence is increasing
# so far
# Search for smallest
# element on the right
# subarray
return countRotation(arr, mid + 1, high)
if (arr[mid] < arr[high]):
# Smallest element lies on the
# left subarray
return countRotation(arr, low, mid - 1)
else:
# Search for the smallest
# element on both subarrays
rightIndex = countRotation(arr,
mid + 1,
high)
leftIndex = countRotation(arr, low,
mid - 1)
if (rightIndex == 0):
return leftIndex
return rightIndex
# Driver code
if __name__ == '__main__':
arr1 = [ 4, 5, 1, 2, 3 ]
N = len(arr1)
print(countRotation(arr1, 0, N - 1))
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to return the
// count of rotations
public static int countRotation(int[] arr,
int low,
int high)
{
// If array is not rotated
if (low > high)
{
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high &&
arr[mid] > arr[mid + 1])
{
// The next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low &&
arr[mid] < arr[mid - 1])
{
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low])
{
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr,
mid + 1,
high);
}
if (arr[mid] < arr[high])
{
// Smallest element lies on the
// left subarray
return countRotation(arr, low,
mid - 1);
}
else
{
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr, low,
mid - 1);
if (rightIndex == 0)
{
return leftIndex;
}
return rightIndex;
}
}
// Driver code
public static void Main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
Console.WriteLine(countRotation(arr1, 0,
arr1.Length - 1));
}
}
// This code is contributed by 29AjayKumar
2
时间复杂度: O(N)
辅助空间: O(1)
有效的方法:
为了优化上述方法,我们将使用二分搜索。我们可以注意到,在排序和旋转之后,给定的数组被分成两半,元素不减少,这是二分查找的唯一先决条件。在数组中执行递归二分查找以找到最小元素的索引。
下面是上述方法的实现:
C++
// C++ program to implement the
// above approach
#include
using namespace std;
// Function to return the
// count of rotations
int countRotation(int arr[], int low,
int high)
{
// If array is not rotated
if (low > high)
{
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high && arr[mid] > arr[mid + 1])
{
// The next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low && arr[mid] < arr[mid - 1])
{
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low])
{
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr, mid + 1,
high);
}
if (arr[mid] < arr[high])
{
// Smallest element lies on the
// left subarray
return countRotation(arr, low,
mid - 1);
}
else
{
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr, low,
mid - 1);
if (rightIndex == 0)
{
return leftIndex;
}
return rightIndex;
}
}
// Driver code
int main()
{
int arr1[] = { 4, 5, 1, 2, 3 };
int N = sizeof(arr1) / sizeof(arr1[0]);
cout << countRotation(arr1, 0, N - 1);
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java Program to implement
// the above approach
public class GFG {
// Function to return the
// count of rotations
public static int countRotation(int[] arr,
int low,
int high)
{
// If array is not rotated
if (low > high) {
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high
&& arr[mid] > arr[mid + 1]) {
// the next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low
&& arr[mid] < arr[mid - 1]) {
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low]) {
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr,
mid + 1,
high);
}
if (arr[mid] < arr[high]) {
// Smallest element lies on the
// left subarray
return countRotation(arr,
low,
mid - 1);
}
else {
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr,
low,
mid - 1);
if (rightIndex == 0) {
return leftIndex;
}
return rightIndex;
}
}
// Driver Program
public static void main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
System.out.println(
countRotation(
arr1,
0, arr1.length
- 1));
}
}
蟒蛇3
# Python3 program to implement the
# above approach
# Function to return the
# count of rotations
def countRotation(arr, low, high):
# If array is not rotated
if (low > high):
return 0
mid = low + (high - low) // 2
# Check if current element is
# greater than the next
# element
if (mid < high and arr[mid] > arr[mid + 1]):
# The next element is
# the smallest
return mid + 1
# Check if current element is
# smaller than it's previous
# element
if (mid > low and arr[mid] < arr[mid - 1]):
# Current element is
# the smallest
return mid
# Check if current element is
# greater than lower bound
if (arr[mid] > arr[low]):
# The sequence is increasing
# so far
# Search for smallest
# element on the right
# subarray
return countRotation(arr, mid + 1, high)
if (arr[mid] < arr[high]):
# Smallest element lies on the
# left subarray
return countRotation(arr, low, mid - 1)
else:
# Search for the smallest
# element on both subarrays
rightIndex = countRotation(arr,
mid + 1,
high)
leftIndex = countRotation(arr, low,
mid - 1)
if (rightIndex == 0):
return leftIndex
return rightIndex
# Driver code
if __name__ == '__main__':
arr1 = [ 4, 5, 1, 2, 3 ]
N = len(arr1)
print(countRotation(arr1, 0, N - 1))
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to return the
// count of rotations
public static int countRotation(int[] arr,
int low,
int high)
{
// If array is not rotated
if (low > high)
{
return 0;
}
int mid = low + (high - low) / 2;
// Check if current element is
// greater than the next
// element
if (mid < high &&
arr[mid] > arr[mid + 1])
{
// The next element is
// the smallest
return mid + 1;
}
// Check if current element is
// smaller than it's previous
// element
if (mid > low &&
arr[mid] < arr[mid - 1])
{
// Current element is
// the smallest
return mid;
}
// Check if current element is
// greater than lower bound
if (arr[mid] > arr[low])
{
// The sequence is increasing
// so far
// Search for smallest
// element on the right
// subarray
return countRotation(arr,
mid + 1,
high);
}
if (arr[mid] < arr[high])
{
// Smallest element lies on the
// left subarray
return countRotation(arr, low,
mid - 1);
}
else
{
// Search for the smallest
// element on both subarrays
int rightIndex = countRotation(arr,
mid + 1,
high);
int leftIndex = countRotation(arr, low,
mid - 1);
if (rightIndex == 0)
{
return leftIndex;
}
return rightIndex;
}
}
// Driver code
public static void Main(String[] args)
{
int[] arr1 = { 4, 5, 1, 2, 3 };
Console.WriteLine(countRotation(arr1, 0,
arr1.Length - 1));
}
}
// This code is contributed by 29AjayKumar
2
时间复杂度: O(N)
对于没有重复的数组,复杂度将为 O(logN)。但是如果数组包含重复项,那么它将递归调用对两半的搜索。所以最坏情况的复杂度将是 O(N)。
辅助空间: O(N)
在最坏的情况下,递归调用堆栈一次将有 N/2 个递归调用。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live