private double helper(int[] A, int aHead, int aTail, int[] B, int bHead, int bTail, int K) {

    int aLen = aTail - aHead + 1;
    int bLen = bTail - bHead + 1;

    // assume A is shorter than B
    // this will reduce half cases
    if (aLen > bLen) {
      return helper(B, bHead, bTail, A, aHead, aTail, K);
    }

    if (aHead > aTail) {
      return B[bHead + K - 1];
    }
    if (bHead > bTail) {
      return A[aHead + K - 1];
    }
    if (K == 1) {
      return Math.min(A[aHead], B[bHead]);
    }

    // SMART !!!
    // this ensures the parts that we keep have at least K element
    // in other word, what we delete later won't contain the Median!!!
    int aMid = Math.min(aLen, K / 2);
    int bMid = K - aMid;

    if (A[aHead + aMid - 1] < B[bHead + bMid - 1]) {

      return helper(A, aHead + aMid, aTail, B, bHead, bTail, K - aMid);

    } else if (A[aHead + aMid - 1] > B[bHead + bMid - 1]) {

      return helper(A, aHead, aTail, B, bHead + bMid, bTail, K - bMid);

    } else {

      return A[aHead + aMid - 1];
    }
  }