Skip to content

197 ReOrder Array (Lai)

Given an array of elements, reorder it as follow:

  • { N1, N2, N3, …, N2k } → { N1, Nk+1, N2, Nk+2, N3, Nk+3, … , Nk, N2k }
  • { N1, N2, N3, …, N2k+1 } → { N1, Nk+1, N2, Nk+2, N3, Nk+3, … , Nk, N2k, N2k+1 }

Try to do it in place.

Assumptions

  • The given array is not null

Examples

  • { 1, 2, 3, 4, 5, 6} → { 1, 4, 2, 5, 3, 6 }
  • { 1, 2, 3, 4, 5, 6, 7, 8 } → { 1, 5, 2, 6, 3, 7, 4, 8 }
  • { 1, 2, 3, 4, 5, 6, 7 } → { 1, 4, 2, 5, 3, 6, 7 }

Solution:

public class Solution {
  public int[] reorder(int[] array) {
    // Write your solution here
    if (array == null || array.length == 0){
      return array;
    }

    if (array.length % 2 == 0){
      helper(array, 0, array.length - 1);
    } else{
      // if array has odd number of elements, we ignore the last one 
      // when do the reordering
      helper(array, 0, array.length - 2);
    }
    return array;
  }

  private static void helper(int[] array, int left, int right){
    int length = right - left + 1;
    // if the subarray has 2 or 0 elements, we can just return
    // as this should be the base case
    if (length <= 2){
      return;
    }
    // Calculate the important mid points
    // 0 1     2 3      4 5     6 7
    // lm: 2, m: 4, rm: 6
    // 0 1    2 3 4        5 6     7 8 9 
    // lm: 2 , m: 5, rm: 7    

    int mid = left + length /2;// 用length 而不用left, right 是为了保证chunk1==chunk3
    int lmid = left + length /4;
    int rmid = left + length * 3 /4; // or mid + length /4;
    // I love yahoo trick
    reverse(array, lmid, mid-1);
    reverse(array, mid, rmid-1);
    reverse(array, lmid, rmid-1);
    // half of the left partition's size = lmid - left
    // 左半边子问题 left to 2*chunk1 size - 1 
    helper(array, left, left + (lmid - left) * 2 -1); // subproblem
    helper(array, left + (lmid-left) * 2, right);
  }

  private static void reverse(int[] array, int left, int right){
    while(left < right){
      int rem = array[left];
      array[left] = array[right];
      array[right] = rem;
      left++;
      right--;
    }
  }
}

// TC: O(n) where n is the length of string
// SC: O(n)
// "I love yahoo Trick" -> 局部顺序保持不变, 但是整体顺序反转
// chunk1 + chunk2 Match chunck3 + chunk4
// 一定保证chunk1的size和chunk3的size 必须相同!
// 3434 完美分割方法
// 这种题 需要记忆 方法来解题