方法(一种杂耍算法) 将数组划分为不同的集合,其中集合的数量等于n和d的GCD,并移动集合中的元素。 如果GCD对于上面的示例数组(n = 7和d = 2)是1,那么元素将仅在一个集合内移动,我们只是从temp = arr [0]开始并继续移动arr [I + d] arr [I]并最终将温度存储在正确的位置。
以下是n = 12且d = 3的示例.GCD为3且
让arr []为{1,2,3,4,5,6,7,8,9,10,11,12}
a)元素首先在第一组中移动 - (参见下图中的移动)
ArrayRotation
arr[] after this step --> {4 2 3 7 5 6 10 8 9 1 11 12}
b)然后在第二组。 arr []在此步骤之后 - > {4 5 3 7 8 6 10 11 9 1 2 12}
c)最后在第三组。 arr []在此步骤之后 - > {4 5 6 7 8 9 10 11 12 1 2 3} / *函数打印数组* / void printArray(int arr [],int size);
/*Function to get gcd of a and b*/
int gcd(int a,int b);
/*Function to left rotate arr[] of siz n by d*/
void leftRotate(int arr[], int d, int n)
{
int i, j, k, temp;
for (i = 0; i < gcd(d, n); i++)
{
/* move i-th values of blocks */
temp = arr[i];
j = i;
while(1)
{
k = j + d;
if (k >= n)
k = k - n;
if (k == i)
break;
arr[j] = arr[k];
j = k;
}
arr[j] = temp;
}
}
/*UTILITY FUNCTIONS*/
/* function to print an array */
void printArray(int arr[], int size)
{
int i;
for(i = 0; i < size; i++)
printf("%d ", arr[i]);
}
/*Function to get gcd of a and b*/
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b, a%b);
}
/* Driver program to test above functions */
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
leftRotate(arr, 2, 7);
printArray(arr, 7);
getchar();
return 0;
}
时间复杂度:O(n) 辅助空间:O(1)
有人可以给我一个很好的解释,说明这个算法是如何工作的,它的渐近复杂度是什么?
答案 0 :(得分:2)
函数中的for循环:
leftRotate(int arr[], int d, int n)
将进行exatcly gcd(d, n)
迭代。现在让我们看看循环中发生了什么:它需要满足所有单元格arr[k]
:k % gcd(d, n) == i
并交换他们。当然,确切地说:n / gcd(d, n)
,它们是循环的一次迭代中函数将进行多少交换。因此,函数的整个渐近时间复杂度将为O(gcd(d, n) * n / gcd(d, n)) == O(n)
。其余代码对时间复杂度没有影响,并且几乎是自我解释。
答案 1 :(得分:-1)
杂耍算法
在这种方法中,将数组划分为M个集合,其中M = GCD(n,k),然后旋转每个集合中的元素。
根据数组的元素数(n)和要对该数组进行的旋转数(k),得出GCD(n,k)个块数。 然后在每个块中,将移动到该块中的相应元素。
所有块中的所有元素移位后,阵列将旋转给定次数。
例如:如果我们想将下面的数组旋转2个位置。 1 2 3 4 5 6
M = GCD(6, 2) = 2;
Initial Array : 1 2 3 4 5 6
First Set Moves : 5 2 1 4 3 6
Second Set Moves : 5 6 1 2 3 4 // The array is rotated twice.
public class Main
{
/*Fuction to get gcd of a and b*/
public static int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
/*Function to left rotate array of by d number of rotations*/
public static void leftRotate(int arr[], int d, int n)
{
int i, j, k, temp;
for (i = 0; i < gcd(d, n); i++) // gcd(d,n) times the loop will iterate
{
/* move i-th values of blocks */
temp = arr[i];
j = i;
while (true) {
k = j + d;
if (k >= n) // The element has to be shifted to its rotated position
k = k - n;
if (k == i) // The element is already in its rotated position
break;
arr[j] = arr[k];
j = k;
}
arr[j] = temp;
}}
// Main function
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7 };
int no_of_rotations = 2;
int n = arr.length;
System.out.println("Array Elements before rotating : ");
for(int i = 0 ; i < n ; i++)
{
System.out.print(arr[i]+ " "); // Printing elements before rotation
}
leftRotate(arr, no_of_rotations, n);
System.out.println("\nArray Elements after rotating : ");
for(int i = 0 ; i < n ; i++)
{
System.out.print(arr[i] + " "); // Printing elements after rotation
} } }