二进制搜索2D数组中的元素(具有重复项)按列进行排序?

时间:2016-02-11 19:54:33

标签: java binary-search

修改

对于2D数组,仅列已排序,但未对行进行排序。下面是我写的方法,首先对每一列进行二进制搜索,然后遍历每一列并计算重复元素。但代码对我不起作用。有人能帮帮我吗?非常感谢!

public static int count(int[][] array, int query) {

    int count = 0;

    for (int j = 0; j < array[0].length; j++) {
        count += biSearch(array, query, j);
    }

    return count;
}

private static int biSearch(int[][] array, int searchItem, int row) {

    // create a 1D array to hold the entries of 2D array's column
    int[] column = new int[array.length];
    int count = 0;
    int low = 0;
    int high = column.length - 1;

    // put 2D array's column into 1D array
    for (int i = 0; i < array.length; i++)
        column[i] = array[i][row];

    // binary search on column array
    while (low < high) {
        int mid = (low + high) / 2;

        if ( column[mid]== searchItem ) {
            while ((mid - 1) >= 0) {
                if (column[mid - 1] == searchItem){ 
                    mid--;
                    count++;
                }
            }
            while ((mid + 1) < (column.length - 1)) {
                if (column[mid + 1] == searchItem){ 
                    mid++;
                    count++;
                }
            }
        } 
        else if ( column[mid] > searchItem)
            high = mid - 1;
        else if (column[mid] <searchItem )
            low = mid + 1;
    }

    return count;
}

1 个答案:

答案 0 :(得分:0)

不确定这是否是唯一的问题,但此代码错误:

if ( column[mid]== searchItem ) {
    while ((mid - 1) >= 0) {
        if (column[mid - 1] == searchItem){ 
            mid--;
            count++;
        }
    }
    while ((mid + 1) < (column.length - 1)) {
        if (column[mid + 1] == searchItem){ 
            mid++;
            count++;
        }
    }
} 

它基本上测试column数组的所有元素,从mid0,而不是从0column.length-1。您不仅要通过整个数组,这会破坏二分搜索的目的,还会访问mid0之间的所有元素两次,这意味着您的计数错误。

更好的方法:

if ( column[mid]== searchItem ) {
    count = 1;
    int temp = mid;
    while (temp > 0 && column[temp - 1] == searchItem) { 
        temp--;
        count++;
    }
    temp = mid;
    while (temp < column.length - 1 && column[temp + 1] == searchItem) {
        temp++;
        count++;
    }
}

要注意的两件事:

  1. 我不会修改mid,因为我们需要第二个while循环的原始值mid

  2. 当我遇到一个不等于searchItem的元素时,我退出每个while循环。由于数组应该被排序(否则二元分离器不能工作),因此不需要遍历整个数组。

  3. P.S。 row中名为biSearch的参数实际上是2D数组列的索引,因此其名称令人困惑。