zoukankan      html  css  js  c++  java
  • [GeeksForGeeks] Cyclically rotate an array by one

    Given an array of integers, write a program that cyclically rotates the array by one.

    Example: given {1,2,3,4,5}, your program should rotate the array to {5,1,2,3,4}

    Algorithm:

    1. save the last element in a temp variable.

    2. starting from the last element until the second element, copy its previous element to be their values.

    3. copy temp to the first element.

    O(n) runtime, O(1) space

     1 public void rotateByOne(int[] arr) {
     2     if(arr == null || arr.length == 0){
     3         return;
     4     }
     5     int temp = arr[arr.length - 1];
     6     for(int i = arr.length - 1; i > 0; i--){
     7         arr[i] = arr[i - 1];
     8     }
     9     arr[0] = temp;
    10 }

    Follow up question:  instead of rotating the given array by one position, rotate it by m positions, m should be controlled by 

    your program caller. if m is positive, it means rotating right, if m is negative, it means rotating left.

    Solution 1. O(m * n) runtime

    Simply call rotateByOne m times.

    Solution 2. O(n) runtime, O(1) space

    Algorithm:  Acheive the rotation by swaping values only one time instead of  m times for each location.

    1. Move arr[0] to a temporary variable t, then move arr[m] to arr[0], arr[2 * m] to arr[m], and so on.(taking all indices into arr modulo arr.length), until we come back to taking the element from arr[0], 

        at which point we instead take t and stop the process.

    2. If step 1 does not move all the elements, repeat step 1 starting from arr[1].  Repeat this step until all the elements are moved, advancing the start element to the next location each iteration.

    The following code only shows the left rotation implementation, the right counter part is similar.

     1 public static void leftRotateByM(int[] arr, int m) {
     2     if(m % arr.length != 0) {
     3         int count = 0;
     4         int startIdx = 0;                   
     5         while(count < arr.length) {
     6             int currIdx = startIdx;
     7             int nextIdx = (currIdx + m) % arr.length;
     8             int temp = arr[startIdx];
     9             while(nextIdx != startIdx) {
    10                 arr[currIdx] = arr[nextIdx];
    11                 currIdx = nextIdx;
    12                 nextIdx = (nextIdx + m) % arr.length;
    13                 count++;
    14             }
    15             arr[currIdx] = temp;
    16             startIdx++;
    17             count++;
    18         }
    19     }
    20 }

    Solution 3. O(n) runtime, O(1) space, using reverse algorithm

    1. decide on the split point depending if it is a left or right rotation.

    2. reverse the splitted array separately, then reverse the whole array.

     1 private void reverse(int[] arr, int start, int end) {
     2     while(start < end) {
     3         arr[start] ^= arr[end];
     4         arr[end] ^= arr[start];
     5         arr[start] ^= arr[end];
     6         start++;
     7         end--;
     8     }
     9 }
    10 public void rotateByMUsingReverse(int[] arr, int m) {
    11     if(arr == null || arr.length == 0 || m % arr.length == 0){
    12         return;
    13     }
    14     m %= arr.length;
    15     int splitIdx = m > 0 ? arr.length - m : m;
    16     reverse(arr, 0, splitIdx - 1);
    17     reverse(arr, splitIdx, arr.length - 1);
    18     reverse(arr, 0, arr.length - 1);
    19 }
  • 相关阅读:
    浅谈UML学习笔记之用例图
    流媒体服务器
    浅谈UML的概念和模型之UML视图
    浅谈UML的概念和模型之UML九种图
    SQL 语法
    吴裕雄--天生自然数据结构:链式队列及基本操作
    吴裕雄--天生自然数据结构:顺序队列
    吴裕雄--天生自然数据结构:队列存储结构
    吴裕雄--天生自然数据结构:链栈及基本操作
    吴裕雄--天生自然数据结构:顺序栈及基本操作
  • 原文地址:https://www.cnblogs.com/lz87/p/7348678.html
Copyright © 2011-2022 走看看