Java 如何旋转数组?
我有以下问题要测试: 将Java 如何旋转数组?,java,arrays,sorting,optimization,time-complexity,Java,Arrays,Sorting,Optimization,Time Complexity,我有以下问题要测试: 将n元素数组向右旋转k步 例如,使用n=7和k=3,数组[1,2,3,4,5,6,7]旋转为 [5,6,7,1,2,3,4]。你知道有多少种不同的方法来解决这个问题 我的中间阵列解决方案: 如果空间是O(n),时间是O(n),我可以创建一个新数组,然后将元素复制到新数组中。然后使用System.arraycopy()更改原始数组 public void rotate(int[]nums,int k){ 如果(k>nums.length) k=k%单位长度; int[]结果=
n
元素数组向右旋转k
步
例如,使用n=7
和k=3
,数组[1,2,3,4,5,6,7]
旋转为
[5,6,7,1,2,3,4]
。你知道有多少种不同的方法来解决这个问题
我的中间阵列解决方案:
如果空间是O(n)
,时间是O(n)
,我可以创建一个新数组,然后将元素复制到新数组中。然后使用System.arraycopy()
更改原始数组
public void rotate(int[]nums,int k){
如果(k>nums.length)
k=k%单位长度;
int[]结果=新的int[nums.length];
for(int i=0;i
但是在
O(1
)空间中使用气泡旋转(如气泡排序)有更好的方法吗?方法1-反转算法(好的):
算法:
旋转(arr[],d,n)
反向(arr[],l,n)
反向(arr[],1,n-d)
反向(arr[],n-d+1,n)
设AB为输入数组的两部分,其中A=arr[0..n-d-1]和B=arr[n-d..n-1]。该算法的思想是:
全部反转以获得(AB)r=BrAr
倒过来拿胸罩。/*Ar是A的反面*/
反向B获得BA./*Br与B相反*/
对于arr[]=[1,2,3,4,5,6,7],d=2,n=7
A=[1,2,3,4,5]和B=[6,7]
反过来,我们得到BrAr=[7,6,5,4,3,2,1]
反过来,我们得到ArB=[7,6,1,2,3,4,5]
反向B,我们得到ArBr=[6,7,5,4,3,1,2]
以下是代码片段:
void righttRotate(int arr[], int d, int n)
{
reverseArray(arr, 0, n-1);
reverseArray(arr, 0, n-d-1);
reverseArray(arr, n-d, n-1);
}
void reverseArray(int arr[], int start, int end)
{
int i;
int temp;
while(start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void leftRotate(int arr[], int d, int n)
{
int i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[n-n];
for (i = 0; i < n-1; i++)
arr[i] = arr[i+1];
arr[n - 1] = temp;
}
void rightRotate(int arr[],int d,int n)
{
反向耳道(arr,0,n-1);
反向耳道(arr,0,n-d-1);
反向耳道(arr,n-d,n-1);
}
void reversearlay(整数arr[],整数开始,整数结束)
{
int i;
内部温度;
while(开始<结束)
{
温度=arr[启动];
arr[start]=arr[end];
arr[end]=温度;
启动++;
结束--;
}
}
方法2-杂耍算法
将数组分成不同的集合,集合数等于n和d的GCD,并在集合内移动元素
如果GCD为1,那么元素将仅在一个集合内移动,我们只需从temp=arr[0]开始,并将arr[I+d]移动到arr[I],最后将temp存储在正确的位置
下面是n=12和d=3的示例。GCD为3,并且
设arr[]为{1,2,3,4,5,6,7,8,9,10,11,12}
void leftRotate(int arr[], int d, int n)
{
int i, j, k, temp;
int gcd = gcd(d, n);
for (i = 0; i < gcd; 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;
}
}
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b, a%b);
}
void leftRotate(int arr[],int d,int n)
{
内部i、j、k、温度;
int-gcd=gcd(d,n);
对于(i=0;i=n)
k=k-n;
如果(k==i)
打破
arr[j]=arr[k];
j=k;
}
arr[j]=温度;
}
}
内部gcd(内部a、内部b)
{
如果(b==0)
返回a;
其他的
返回gcd(b,a%b);
}
时间复杂度:O(n)
辅助空间:O(1)
方法3-逐个旋转:
右三酸盐(arr[],d,n)
开始
对于i=0到ivoid righttRotate(int arr[], int d, int n)
{
reverseArray(arr, 0, n-1);
reverseArray(arr, 0, n-d-1);
reverseArray(arr, n-d, n-1);
}
void reverseArray(int arr[], int start, int end)
{
int i;
int temp;
while(start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void leftRotate(int arr[], int d, int n)
{
int i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[n-n];
for (i = 0; i < n-1; i++)
arr[i] = arr[i+1];
arr[n - 1] = temp;
}
void leftRotate(int arr[],int d,int n)
{
int i;
对于(i=0;i
时间复杂度:O(n*d)
辅助空间:O(1)
以下代码将完成您的工作。这是右转
public void rightrotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
当
k
为负值时,它会向左旋转。
空间是O(1),时间是O(n)
static void rotate(int[]num,int k){
int n=num.length;
k=k%n;
如果(k<0)k+=n;
int[]结果=新的int[n];
数组复制(num,0,result,k,n-k);
数组复制(num,n-k,result,0,k);
数组复制(结果,0,num,0,n);
}
这是一个旋转阵列的简单解决方案
public class ArrayRotate {
public int[] rotateArray(int array[], int k) {
int newArray[] = new int[array.length];
for (int i = 0; i < array.length; i++) {
newArray[(i + k) % array.length] = array[i];
}
System.arraycopy(newArray, 0, array, 0, array.length);
return newArray;
}
public static void main(String[] args) {
int array[] = { 1, 2, 3, 4, 5, 6, 7 };
ArrayRotate rotate = new ArrayRotate();
rotate.display(rotate.rotateArray(array, 3));
}
public void display(int array[]) {
for (int i : array) {
System.out.print(i + ",");
}
}
}
公共类ArrayRotate{
公共整数[]旋转数组(整数数组[],整数k){
int newArray[]=newint[array.length];
for(int i=0;i
运行时复杂性为O(n)
还有其他几种算法可以实现同样的效果
- 使用临时数组
- 逐个旋转
- 杂耍算法
public class ArrayRotate { public int[] rotateArray(int array[], int k) { int newArray[] = new int[array.length]; for (int i = 0; i < array.length; i++) { newArray[(i + k) % array.length] = array[i]; } System.arraycopy(newArray, 0, array, 0, array.length); return newArray; } public static void main(String[] args) { int array[] = { 1, 2, 3, 4, 5, 6, 7 }; ArrayRotate rotate = new ArrayRotate(); rotate.display(rotate.rotateArray(array, 3)); } public void display(int array[]) { for (int i : array) { System.out.print(i + ","); } } }
public static void rotateArrayByS(int[] ar, int s) { int len = ar.Length, ind = 0, temp1 = ar[0], temp2 /*temp1 and temp2 for switching elements*/, loopCount /*rotations starting at the first s elemtns of ar*/ = 0; s %= len; while (loopCount < s) { int indAtBeg = ind; temp1 = ar[ind]; bool done = false; while (!done) { if (ind < s) loopCount++; ind = (ind + s) % len; //cycle detected if (ind == indAtBeg) done = true; //switch the elements temp2 = ar[ind]; ar[ind] = temp1; temp1 = temp2; } ++ind; } }
last=number_holder[n-1]; first=number_holder[0]; //rotation number_holder[0]=last; for(i=1;i<n;i++) { last=number_holder[i]; number_holder[i]=first; first=last; }
for(i=1;i<n;i++) { System.out.println(number_holder[i]); }
public class Solution { public static void main(String[] args) { int k = 3; int a[] = {1,2,3,4,5,6,7}; ArrayUtil.leftRotate(a, k); for (int i : a) System.out.println(i); } } class ArrayUtil { public static final boolean checkIndexOutOfRange(int[] array, int index) { if (index < 0 || index > array.length) return true; return false; } public static final void swap(int[] array, int i, int j) { if (checkIndexOutOfRange(array, i) || checkIndexOutOfRange(array, j)) return; int t = array[i]; array[i] = array[j]; array[j] = t; } public static final void reverse(int[] array, int startIndex, int endIndex) { if (checkIndexOutOfRange(array, startIndex) || checkIndexOutOfRange(array, endIndex)) return; while (startIndex < endIndex) { swap(array, startIndex, endIndex); startIndex++; endIndex--; } } public static final void reverse(int[] array) { reverse(array, 0, array.length - 1); } public static final void leftRotate(int[] array, int shift) { int arrayLength = array.length; if (shift >= arrayLength) shift %= arrayLength; reverse(array, 0, shift - 1); reverse(array, shift, arrayLength - 1); reverse(array); } }
#include <iostream> #include <vector> // same logic with STL implementation, but simpler, since no return value needed. template <typename Iterator> void rotate_by_gcd_like_swap(Iterator first, Iterator mid, Iterator last) { if (first == mid) return; Iterator old = mid; for (; mid != last;) { std::iter_swap(first, mid); ++first, ++mid; if (first == old) old = mid; // left half exhausted else if (mid == last) mid = old; } } // same logic with STL implementation template <typename Iterator> Iterator rotate_by_gcd_like_swap_then_return_new_mid(Iterator first, Iterator mid, Iterator last) { if (first == mid) return last; if (mid == last) return first; Iterator old = mid; for(;;) { std::iter_swap(first, mid); ++first, ++mid; if (first == old) old = mid; if (mid == last) break; } Iterator result = first; // when first time `mid == last`, the position of `first` is the new `mid`. for (mid = old; mid != last;) { std::iter_swap(first, mid); ++first, ++mid; if (first == old) old = mid; else if (mid == last) mid = old; } return result; } int main() { using std::cout; std::vector<int> v {0,1,2,3,4,5,6,7,8,9}; cout << "before rotate: "; for (auto x: v) cout << x << ' '; cout << '\n'; int k = 7; rotate_by_gcd_like_swap(v.begin(), v.begin() + k, v.end()); cout << " after rotate: "; for (auto x: v) cout << x << ' '; cout << '\n'; cout << "sz = " << v.size() << ", k = " << k << '\n'; }
#include <cmath> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; void rotateLeft(int n,int r) { vector<long int> vec(n); int j = n; // get the position of starting index after r left rotations. while(r!=0) { --j; if(j==0) j = n; --r; } for(long int i=0;i<n;++i) { // simply read the input from there and increment j using modulus operator. cin>>vec[j]; j = (j+1)%n; } // print the array for(long int i=0;i<n;++i) cout<<vec[i]<<" "; } int rotateRight (int n,int r) { // get the position of starting index after r left rotations. int j = r % n; vector<long int> vec(n); for(int i=0;i<n;i++) { cin>>vec[j]; j=(j+1)%n; } for(int i=0;i<n;i++) cout<<vec[i]<<" "; } int main() { long int n,r; // n stands from number of elements in array and r stands for rotations. cin>>n>>r; // Time Complexity: O(n+r) Space Complexity: O(1) rotateLeft(n,r); // Time Complexity: O(n) Space Complexity: O(1) rotateRight(n,r); return 0; }
#include <stdio.h> int main(void) { int arr[7] = {1,2,3,4,5,6,7}; int new_arr[7] = {0}; int k = 3; int len = 7; int i=0; for (i = (len-1); i>=0; i--) { if ((i+k) >= len) { new_arr[(i+k-len)] = arr[i]; } else { new_arr[(i+k)] = arr[i]; } } for (i=0;i<len;i++) { printf("%d ", new_arr[i]); } return 0; }
def reverse(arr,start , end): while(start <= end): arr[start] , arr[end] = arr[end] , arr[start] start = start+1 end = end-1 arr = [1,2,3,4,5,6,7] n = 7 k = 2 reverse(arr,0,n-1) # [7,6,5,4,3,2,1] reverse(arr,0,n-1-k) # [3,4,5,6,7,2,1] reverse(arr,n-k,n-1) # [3,4,5,6,7,1,2] print arr # [3, 4, 5, 6, 7, 8, 9, 1, 2]
import java.util.*; public class ArrayRotation { private static Scanner sc; public static void main(String[] args) { int n,k; sc = new Scanner(System.in); System.out.print("Enter the size of array: "); n = sc.nextInt(); int[] a = new int[n]; System.out.print("Enter the "+n+" elements in the list: "); for(int i=0;i<n;i++) a[i] = sc.nextInt(); System.out.print("Enter the number of left shifts to array: "); k = sc.nextInt(); System.out.print("Array before "+k+" shifts: "); display(a); leftRoation(a,k); System.out.println(); System.out.print("Array after "+k+" left shifts: "); display(a); rightRoation(a,k); System.out.println(); System.out.print("Array after "+k+" right shifts: "); display(a); } public static void leftRoation(int[] a, int k){ int temp=0, j; for(int i=0;i<k;i++){ temp = a[0]; // j=0; // both codes work i.e. for loop and while loop as well // while(j<a.length-1){ // a[j]=a[j+1]; // j++; // } for(j=0;j<a.length-1;j++) a[j]=a[j+1]; a[j]=temp; } } public static void rightRoation(int[] a, int k){ int temp=0, j; for(int i=0;i<k;i++){ temp = a[a.length-1]; for(j=a.length-1;j>0;j--) a[j]=a[j-1]; a[j]=temp; } } public static void display(int[] a){ for(int i=0;i<a.length;i++) System.out.print(a[i]+" "); } } /****************** Output ******************** Enter the size of array: 5 Enter the 5 elements in the list: 1 2 3 4 5 Enter the number of left and right shifts to array: 2 Array before 2 shifts: 1 2 3 4 5 Array after 2 left shifts: 3 4 5 1 2 Array after 2 right shifts: 1 2 3 4 5 // here the left shifted array is taken as input and hence after right shift it looks same as original array. **********************************************/
public static int[] arrayLeftRotation(int[] a, int n, int k) { if (k == 0) return a; for (int i = 0; i < k; i++) { int retenue = a[0]; int[] copie = java.util.Arrays.copyOfRange(a, 1, n ); for (int y = 0; y <= copie.length - 1 ; y++) { a[y] = copie[y]; } a[n-1] = retenue; } return a; }
def array_rotate(arr) i, j = arr.length - 1, 0 arr[j],arr[i], i, j = arr[i], arr[j], i - 1, j + 1 while(j<arr.length/2) puts "#{arr}" end
public int[] solution(int[] A, int K) { int len = A.length; //Create an empty array with same length as A int arr[] = new int[len]; for (int i = 0; i < len; i++) { int nextIndex = i + K; if (nextIndex >= len) { // wraps the nextIndex by same number of K steps nextIndex = nextIndex % len; } arr[nextIndex] = A[i]; } return arr; }
>>> k = 3 >>> arr = [1,2,3,4,5,6,7] >>> actual_rot = k % len(arr) >>> left_ar = arr[:-actual_rot] >>> right_ar = arr[-actual_rot:] >>> result = right_ar + left_ar >>> result [5, 6, 7, 1, 2, 3, 4]
public static void rotateAnArrayUsingTemp(int arr[], int d, int n) { int temp[] = new int[d]; int tempIndex = 0; for (int i = 0; i < d; i++) { temp[i] = arr[i]; } for (int i = 0; i < arr.length - d; i++) { arr[i] = arr[i + d]; } for (int i = arr.length - d; i < arr.length; i++) { arr[i] = temp[tempIndex++]; } }
a = [1,2,3,4,5,6] b = a[:] k = 2 for i in range(len(a)): a[(i + k) % len(a)] = b[i]## (rotate right by k steps) #a[(i - k) % len(a)] = b[i]## (rotate left by k steps) print(a)
def rotLeft(a, d): data = a n = d get = data[n:len(data)] remains = data[0:n] data.clear() for i in get: data.append(i) for x in remains: data.append(x) return data
for (int i = 0; i < k; i++) { for (int j = nums.length - 1; j > 0; j--) { int temp = nums[j]; nums[j] = nums[j - 1]; nums[j - 1] = temp; } } return nums;
if (k > arr.length) { k = k % arr.length; } int n = arr.length - k; int count = 0; outer: for (int i = arr.length - 1; i >= n; i--) { int temp = arr[i]; inner: for (int j = i - 1; j >= 0; j--) { arr[j + 1] = arr[j]; if (j == 0) { int temp2 = arr[j]; arr[j] = temp; i = arr.length; count++; if (count == k) { break outer; } } } }