考虑按递增顺序排序的不同数字的数组。该阵列已旋转(顺时针)k 次。给定这样一个数组,找出 k 的值。
例子:
Input : arr[] = {15, 18, 2, 3, 6, 12}
Output: 2
Explanation : Initial array must be {2, 3,
6, 12, 15, 18}. We get the given array after
rotating the initial array twice.
Input : arr[] = {7, 9, 11, 12, 5}
Output: 4
Input: arr[] = {7, 9, 11, 12, 15};
Output: 0
方法一(使用线性搜索)
如果我们仔细查看示例,我们会注意到旋转次数等于最小元素的索引。一个简单的线性解决方案是找到最小元素并返回其索引。下面是这个想法的 C++ 实现。
C++
// C++ program to find number of rotations
// in a sorted and rotated array.
#include
using namespace std;
// Returns count of rotations for an array which
// is first sorted in ascending order, then rotated
int countRotations(int arr[], int n)
{
// We basically find index of minimum
// element
int min = arr[0], min_index;
for (int i=0; i arr[i])
{
min = arr[i];
min_index = i;
}
}
return min_index;
}
// Driver code
int main()
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = sizeof(arr)/sizeof(arr[0]);
cout << countRotations(arr, n);
return 0;
}
Java
// Java program to find number of
// rotations in a sorted and rotated
// array.
import java.util.*;
import java.lang.*;
import java.io.*;
class LinearSearch
{
// Returns count of rotations for an
// array which is first sorted in
// ascending order, then rotated
static int countRotations(int arr[], int n)
{
// We basically find index of minimum
// element
int min = arr[0], min_index = -1;
for (int i = 0; i < n; i++)
{
if (min > arr[i])
{
min = arr[i];
min_index = i;
}
}
return min_index;
}
// Driver program to test above functions
public static void main (String[] args)
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = arr.length;
System.out.println(countRotations(arr, n));
}
}
// This code is contributed by Chhavi
Python3
# Python3 program to find number
# of rotations in a sorted and
# rotated array.
# Returns count of rotations for
# an array which is first sorted
# in ascending order, then rotated
def countRotations(arr, n):
# We basically find index
# of minimum element
min = arr[0]
for i in range(0, n):
if (min > arr[i]):
min = arr[i]
min_index = i
return min_index;
# Driver code
arr = [15, 18, 2, 3, 6, 12]
n = len(arr)
print(countRotations(arr, n))
# This code is contributed by Smitha Dinesh Semwal
C#
// c# program to find number of
// rotations in a sorted and rotated
// array.
using System;
class LinearSearch
{
// Returns count of rotations for an
// array which is first sorted in
// ascending order, then rotated
static int countRotations(int []arr, int n)
{
// We basically find index of minimum
// element
int min = arr[0], min_index = -1;
for (int i = 0; i < n; i++)
{
if (min > arr[i])
{
min = arr[i];
min_index = i;
}
}
return min_index;
}
// Driver program to test above functions
public static void Main ()
{
int []arr = {15, 18, 2, 3, 6, 12};
int n = arr.Length;
Console.WriteLine(countRotations(arr, n));
}
}
// This code is contributed by vt_m.
PHP
$arr[$i])
{
$min = $arr[$i];
$min_index = $i;
}
}
return $min_index;
}
// Driver code
$arr = array(15, 18, 2,
3, 6, 12);
$n = sizeof($arr);
echo countRotations($arr, $n);
// This code is contributed
// by ajit
?>
Javascript
C++
// Binary Search based C++ program to find number
// of rotations in a sorted and rotated array.
#include
using namespace std;
// Returns count of rotations for an array which
// is first sorted in ascending order, then rotated
int countRotations(int arr[], int low, int high)
{
// This condition is needed to handle the case
// when the array is not rotated at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
int mid = low + (high - low)/2; /*(low + high)/2;*/
// Check if element (mid+1) is minimum element.
// Consider the cases like {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid+1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left half or
// right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid-1);
return countRotations(arr, mid+1, high);
}
// Driver code
int main()
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = sizeof(arr)/sizeof(arr[0]);
cout << countRotations(arr, 0, n-1);
return 0;
}
Java
// Java program to find number of
// rotations in a sorted and rotated
// array.
import java.util.*;
import java.lang.*;
import java.io.*;
class BinarySearch
{
// Returns count of rotations for an array
// which is first sorted in ascending order,
// then rotated
static int countRotations(int arr[], int low,
int high)
{
// This condition is needed to handle
// the case when array is not rotated
// at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
// /*(low + high)/2;*/
int mid = low + (high - low)/2;
// Check if element (mid+1) is minimum
// element. Consider the cases like
// {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid + 1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void main (String[] args)
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = arr.length;
System.out.println(countRotations(arr, 0, n-1));
}
}
// This code is contributed by Chhavi
Python3
# Binary Search based Python3
# program to find number of
# rotations in a sorted and
# rotated array.
# Returns count of rotations for
# an array which is first sorted
# in ascending order, then rotated
def countRotations(arr):
n = len(arr)
start = 0
end = n-1
# finding the index of minimum of the array
# index of min would be equal to number to rotation
while start<=end:
mid = start+(end-start)//2
# Calulating the previous(prev) and next(nex) index of mid
prev = (mid-1+n)%n
nex = (mid+1)%n
# Checking if mid is minimum
if arr[mid]arr[end]: start = mid+1
else: return 0
# Driver code
arr = [18,12]
n = len(arr)
print(countRotations(arr))
# This code is contributed by Smitha Dinesh Semwal
C#
// C# program to find number of
// rotations in a sorted and rotated
// array.
using System;
class BinarySearch
{
// Returns count of rotations for an array
// which is first sorted in ascending order,
// then rotated
static int countRotations(int []arr, int low, int high)
{
// This condition is needed to handle
// the case when array is not rotated
// at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
// /*(low + high)/2;*/
int mid = low + (high - low)/2;
// Check if element (mid+1) is minimum
// element. Consider the cases like
// {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid + 1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void Main ()
{
int []arr = {15, 18, 2, 3, 6, 12};
int n = arr.Length;
Console.WriteLine(countRotations(arr, 0, n-1));
}
}
// This code is contributed by vt_m.
PHP
$low &&
$arr[$mid] < $arr[$mid - 1])
return (int)($mid);
// Decide whether we need
// to go to left half or
// right half
if ($arr[$high] > $arr[$mid])
return countRotations($arr, $low,
$mid - 1);
return countRotations($arr,
$mid + 1,
$high);
}
// Driver code
$arr = array(15, 18, 2, 3, 6, 12);
$n = sizeof($arr);
echo countRotations($arr, 0, $n - 1);
// This code is contributed bu ajit
?>
Javascript
输出:
2
时间复杂度: O(n)
辅助空间: O(1)
方法二(高效使用二分查找)
在这里我们也找到了最小元素的索引,但使用了二分搜索。该想法基于以下事实:
- 最小元素是前一个大于它的唯一元素。如果没有前一个元素,则没有旋转(第一个元素是最小的)。我们通过将中间元素与 (mid-1)’th 和 (mid+1)’th 元素进行比较来检查中间元素的条件。
- 如果最小元素不在中间(既不是 mid 也不是 mid + 1),则最小元素位于左半边或右半边。
- 如果中间元素小于最后一个元素,则最小元素位于左半部分
- 否则最小元素位于右半部分。
下面是从这里获取的实现。
C++
// Binary Search based C++ program to find number
// of rotations in a sorted and rotated array.
#include
using namespace std;
// Returns count of rotations for an array which
// is first sorted in ascending order, then rotated
int countRotations(int arr[], int low, int high)
{
// This condition is needed to handle the case
// when the array is not rotated at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
int mid = low + (high - low)/2; /*(low + high)/2;*/
// Check if element (mid+1) is minimum element.
// Consider the cases like {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid+1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left half or
// right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid-1);
return countRotations(arr, mid+1, high);
}
// Driver code
int main()
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = sizeof(arr)/sizeof(arr[0]);
cout << countRotations(arr, 0, n-1);
return 0;
}
Java
// Java program to find number of
// rotations in a sorted and rotated
// array.
import java.util.*;
import java.lang.*;
import java.io.*;
class BinarySearch
{
// Returns count of rotations for an array
// which is first sorted in ascending order,
// then rotated
static int countRotations(int arr[], int low,
int high)
{
// This condition is needed to handle
// the case when array is not rotated
// at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
// /*(low + high)/2;*/
int mid = low + (high - low)/2;
// Check if element (mid+1) is minimum
// element. Consider the cases like
// {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid + 1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void main (String[] args)
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = arr.length;
System.out.println(countRotations(arr, 0, n-1));
}
}
// This code is contributed by Chhavi
蟒蛇3
# Binary Search based Python3
# program to find number of
# rotations in a sorted and
# rotated array.
# Returns count of rotations for
# an array which is first sorted
# in ascending order, then rotated
def countRotations(arr):
n = len(arr)
start = 0
end = n-1
# finding the index of minimum of the array
# index of min would be equal to number to rotation
while start<=end:
mid = start+(end-start)//2
# Calulating the previous(prev) and next(nex) index of mid
prev = (mid-1+n)%n
nex = (mid+1)%n
# Checking if mid is minimum
if arr[mid]arr[end]: start = mid+1
else: return 0
# Driver code
arr = [18,12]
n = len(arr)
print(countRotations(arr))
# This code is contributed by Smitha Dinesh Semwal
C#
// C# program to find number of
// rotations in a sorted and rotated
// array.
using System;
class BinarySearch
{
// Returns count of rotations for an array
// which is first sorted in ascending order,
// then rotated
static int countRotations(int []arr, int low, int high)
{
// This condition is needed to handle
// the case when array is not rotated
// at all
if (high < low)
return 0;
// If there is only one element left
if (high == low)
return low;
// Find mid
// /*(low + high)/2;*/
int mid = low + (high - low)/2;
// Check if element (mid+1) is minimum
// element. Consider the cases like
// {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid + 1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void Main ()
{
int []arr = {15, 18, 2, 3, 6, 12};
int n = arr.Length;
Console.WriteLine(countRotations(arr, 0, n-1));
}
}
// This code is contributed by vt_m.
PHP
$low &&
$arr[$mid] < $arr[$mid - 1])
return (int)($mid);
// Decide whether we need
// to go to left half or
// right half
if ($arr[$high] > $arr[$mid])
return countRotations($arr, $low,
$mid - 1);
return countRotations($arr,
$mid + 1,
$high);
}
// Driver code
$arr = array(15, 18, 2, 3, 6, 12);
$n = sizeof($arr);
echo countRotations($arr, 0, $n - 1);
// This code is contributed bu ajit
?>
Javascript
输出:
2
时间复杂度: O(Log n)
辅助空间: O(1) 如果我们使用迭代二分搜索则使用(读者可以参考二分搜索文章进行迭代二分搜索)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。