编程之美--2.17数组循环移位
1. 问题
设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。
解法1:每次将整个数组的每个元素向右移动1位,总共循环进行K次,时间复杂度为O(N^2)
//方法1,每一右移动1位,总共进行K次 public static void RightShift1(int[] arr, int K){ while(K!=0){ int temp = arr[arr.length-1]; for(int i = arr.length-1 ; i > 0 ; i--){ arr[i] = arr[i-1]; } K--; arr[0] = temp; } }
解法2:分别将前len-k个元素、后K个元素置为逆序,然后再将整个数组置为逆序,时间复杂度为O(N)
//方法2,逆序的方法分别将前len-K个元素、后K个元素逆序,然后将整个数组逆序 public static void RightShift2(int[] arr, int K){ int len = nums.length; if(len==0||len==1) return; k = k%len; Reverse(nums, 0, len - k - 1); Reverse(nums, len - k, len - 1); Reverse(nums, 0, len - 1); } public static void Reverse(int[] arr , int left , int right){ while(left < right){ int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; right--; } }
错误的!!!!!!!!解法3:解法1的改进,直接将第i个元素向右移动K位,再将第i+K个元素向右移动K位...以此类推,直到下标回到初始位置为止。
时间复杂度为O(N)
//方法3,移位的方法,第i个元素向右移动K位,再将i+K个元素向右移动K位,以此类推... public static void RightShift(int[] arr, int K, int len){//将数组向右循环移动K位 int temp = arr[len-1]; int i = len-1; arr[i] = arr[(i+len-K)%len]; i = (i+len-K)%len; while(i!=len-1){ arr[i] = arr[(i+len-K)%len]; i = (i+len-K)%len; }//循环中实际上最后一次循环不应该进行 arr[6+K-len] = temp; }
main函数
public static void main(String[] args) { ////////////初始值////////////////////// int[] arr = {1,2,3,4,5,6,7}; for(int i = 0 ; i < arr.length ; i++){ System.out.print(arr[i]+" "); } int K = 3; System.out.println(); ////////////方法1////////////////////// RightShift1(arr,K); for(int i = 0 ; i < arr.length ; i++){ System.out.print(arr[i]+" "); } System.out.println(); ////////////方法2///////////////////// int[] arr2 = {1,2,3,4,5,6,7}; RightShift2(arr2,K); for(int i = 0 ; i < arr.length ; i++){ System.out.print(arr[i]+" "); } System.out.println(); ////////////方法3///////////////////// int[] arr3 = {1,2,3,4,5,6,7}; RightShift(arr3,K,arr3.length); for(int i = 0 ; i < arr.length ; i++){ System.out.print(arr[i]+" "); } }
运行结果:
1 2 3 4 5 6 7
5 6 7 1 2 3 4
5 6 7 1 2 3 4
5 6 7 1 2 3 4

浙公网安备 33010602011771号