找到中位数给出三个元素的指数

时间:2015-09-14 18:09:09

标签: java algorithm

作为我的QuickSort算法的一部分,我试图在给出第一个,中间和最后一个元素的索引的情况下从Arraylist中找到中值。我使用了几个if / else语句作为查找它的方法,但它不对,逻辑相当复杂。

注意:不能选择对数组进行排序。

public static int findMedian(ArrayList <Integer> A, int first, int mid, int last) {
    if(first == mid || first == last || last == mid) {
        return first;
    }
    if(A.get(first) >= A.get(last)) {
        if(A.get(first) <= A.get(mid)) {
            return first;
        }
        else if(A.get(last) >= A.get(mid)) {
            return last;
        }
        return mid;
    }
    else {
        if(A.get(first) > A.get(mid)) {
            return first;
        }
        else if(A.get(mid) > A.get(last)) {
            return last;
        }
        return mid;
    }
}

3 个答案:

答案 0 :(得分:1)

这种方法怎么样?

public static int findMedian(ArarayList<Integer> A, int first, int mid, int \last) {
    if (first == mid || first == last || last == mid)
        return first;

    int v = (A.get(first) >= A.get(mid)  ? 1 : 0) +
            (A.get(first) >= A.get(last) ? 2 : 0) +
            (A.get(mid)   >= A.get(last) ? 4 : 0);

    switch (v) {
    case 0: /* a < b && a < c && b < c */
        return mid;
    case 1: /* a >= b && a < c && b < c */
        return first;
    case 2: /* a < b && a >= c && b < c -> not possible */
        return -1;
    case 3: /* a >= b && a >= c && b < c */
        return last;
    case 4: /* a < b && a < c && b >= c */
        return last;
    case 5: /* a >= b && a < c && b >= c -> not possible */
        return -1;
    case 6: /* a < b && a >= c && b >= c */
        return first;
    case 7: /* a >= b && a >= c && b >= c */
        return mid;
    }

    /* won't come here */
    return first;
}

或者以更紧凑的形式。

public static int findMedian(ArarayList<Integer> A, int first, int mid, int \last) {    
    if (first == mid || first == last || last == mid)
        return first;

    int result[] = new int[] { mid, first, -1, last, last, -1, first, mid };

    int v = (A.get(first) >= A.get(mid)  ? 1 : 0) +
            (A.get(first) >= A.get(last) ? 2 : 0) +
            (A.get(mid)   >= A.get(last) ? 4 : 0);

    return result[v];
}

答案 1 :(得分:0)

有一件看起来很奇怪的事情是,如果最后==中,你先退回。

如果你只是删除这些行,也许它会更好:

    if(first == mid || first == last || last == mid) {
        return first;
    }

答案 2 :(得分:0)

您是否能够在索引上使用Arrays.sort(我意识到您不能在列表本身上使用排序)?如果是这样,您可以按值对索引进行排序,然后选择中间的索引:

int findMedian(List<Integer> list, int first, int mid, int last) {
    int[] indices = {first, mid, last};
    Arrays.sort(indices, (i1, i2) -> list.get(i1) - list.get(i2));
    return indices[1];
}

如果您因任何原因无法使用sort,那么您可以进行自己的简单插入排序:

int findMedian(List<Integer> list, int first, int mid, int last) {
    List<Integer> indices = new ArrayList<>();
    for (int i: Arrays.asList(first, mid, last) {
        int j = 0;
        while (j < indices.size() && list.get(i) > list.get(j))
            j++;
        indices.add(j, i);
    }
    return indices.get(1);
}

如果您不想使用其中任何一个,那么我建议您完全明确if个语句:

if (list.get(first) >= list.get(mid) && list.get(first) <= list.get(last)) {
    return first;
else if (list.get(mid) >= list.get(first) && list.get(mid) <= list.get(last)) {
    return mid;
} else {
    return last;
}