给定排序数组(按绝对值排序)和数字,找到数字的位置

时间:2015-05-10 07:42:05

标签: java arrays

假设我们有一个数组

a[] ={1,2,-3,3,-3,-3,4,-4,5}

找到3的位置(这将是3)

答案没有多个索引。

它必须高效,而不是线性。

我在考虑对数组进行二进制搜索,但是我想比较绝对值,而不是比较原始值。 abs(a [i])和abs(n)[n是输入数字]。然后,如果值相等,我进行另一次比较,现在使用原始值a [i]和n。

但我遇到了一个问题,如果我在上述情况下使用相同的数组{1,2,-3,3,-3,-3,4,-4,5},我正在寻找3,有多个-3阻碍了(因此,我必须检查原始值a [i]和n是否不起作用,我必须检查[i + 1]和[i-1] ]。)

好的我现在只是在闲聊。我觉得这太难了吗?

帮帮我谢谢! :d

2 个答案:

答案 0 :(得分:2)

这是一个修改过的二进制搜索问题。这个和常规二进制搜索之间的区别在于,您需要根据排序标准查找并测试比较相等的所有元素。

我会:

  • 使用调整后的二进制搜索算法查找匹配的最左侧元素的索引

  • 遍历索引,直到找到要查找的元素,或者绝对值不再匹配的元素。

第一步应该是O(logN)。如果您假设元素值均匀分布,则第二步平均为O(1)。 (第二步的最坏情况是O(N);例如,当元素都具有相同的绝对值,而你想要的那个是数组中的最后一个。)

答案 1 :(得分:0)

以下是解决问题的方法:

/**
 * @param a array sorted by absolute value
 * @param key value to find (must be positive)
 * @return position of the first occurence of the key or -1 if key not found
 */
public static int binarySearch(int[] a, int key) {
    int low = 0;
    int high = a.length-1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = Math.abs(a[mid]);

        if (midVal < key)
            low = mid + 1;
        else if (midVal > key || (midVal == key && mid > 0 && Math.abs(a[mid-1]) == key))
            high = mid - 1;
        else
            return mid; // key found
    }
    return -1; // key not found.
}

这是JDK对Arrays.binarySearch的修改。有几处变化。首先,我们比较绝对值。其次,因为你不想要任何关键位置,而是第一个,我修改了一个条件:如果我们找到了一个键,我们检查前一个数组项是否具有相同的值。如果是,那么我们继续搜索。即使对于太多的值等于key的特殊情况,这种算法仍然是O(log N)