Finding the median value of an array?

后端 未结 9 1322
伪装坚强ぢ
伪装坚强ぢ 2020-12-03 14:58

I was wondering if it was possible to find the median value of an array? For example, suppose I have an array of size nine. Would it possible to find the middle slot of this

9条回答
  •  Happy的楠姐
    2020-12-03 15:16

    There is another alternative - in general, the suggestions here either suggest sorting the array then taking the median from such an array or relying on a (external) library solution. Fastest sorting algorithms today are linearithmic, on average, but it is possible to do better than that for the purposes of median calculation.

    The quickest algorithm to compute median from an unsorted array is QuickSelect, which, on average, finds the median in time proportional to O(N). The algorithm takes array as argument, together with int value k (the order statistic, i.e. k-th smallest element in the array). The value of k, in this case, is simply N/2, where N is array length.

    Implementation is little tricky to get right but here is an example which relies on Comparable interface and Collections.shuffle() without any external dependencies.

    public final class QuickSelectExample {
    
        public static > T select(T[] a, int k) {
            if (k < 1) throw new IllegalStateException("Invalid k - must be in [1, inputLength].");
            if (k > a.length) throw new IllegalStateException("K-th element exceeds array length.");
            Collections.shuffle(Arrays.asList(a));
            return find(a, 0, a.length - 1, k - 1);
        }
    
        private static > T find(T[] a, int lo, int hi, int k) {
            int mid = partition(a, lo, hi);
    
            if (k == mid) return a[k];
            else if (k < mid) return find(a, lo, mid - 1, k); // search left subarray
            else if (k > mid) return find(a, mid + 1, hi, k); // search right subarray
            else throw new IllegalStateException("Not found");
        }
    
        private static > int partition(T[] a, int lo, int hi) {
            T pivot = a[lo];
            int i = lo + 1;
            int j = hi;
    
            while (true) { // phase 1
                while (i <= hi && (less(a[i], pivot) || eq(a[i], pivot))) // is a[i] >= pivot?
                    i++;
    
                while (j >= i && !less(a[j], pivot))  // is a[j] <= pivot?
                    j--;
    
                if (i >= j) break;
                exch(a, i, j);
            }
            exch(a, lo, j); // phase 2
            return j;
        }
    
        private static > boolean less(T x, T y) {
            return x.compareTo(y) < 0;
        }
    
        private static > boolean eq(T x, T y) {
            return x.compareTo(y) == 0;
        }
    }
    

    The code produces the following order statistics for these input arrays:

                "                  Input Array                    |                                                           Actual Output [format: (index k -> array element)]                                                           ", //
                "                                                 |                                                                                                                                                                        ", //
                "       [S, O, R, T, E, X, A, M, P, L, E]         |                            [(1 -> A), (2 -> E), (3 -> E), (4 -> L), (5 -> M), (6 -> O), (7 -> P), (8 -> R), (9 -> S), (10 -> T), (11 -> X)]                            ", //
                "   [P, A, B, X, W, P, P, V, P, D, P, C, Y, Z]    |            [(1 -> A), (2 -> B), (3 -> C), (4 -> D), (5 -> P), (6 -> P), (7 -> P), (8 -> P), (9 -> P), (10 -> V), (11 -> W), (12 -> X), (13 -> Y), (14 -> Z)]           " //
    

提交回复
热议问题