如何在min和max之间找到子阵列

时间:2013-09-18 09:31:56

标签: arrays algorithm data-structures

我有一个Sorted数组。我们假设

{4,7,9,12,23,34,56,78}给定min和max我想以有效的方式在min和max之间找到数组中的元素。

Cases:min=23 and max is 78  op:{23,34,56,78}
 min =10 max is 65 op:{12,23,34,56}

min 0 and max is 100 op:{4,7,9,12,23,34,56,78}

Min 30 max= 300:{34,56,78}

Min =100 max=300 :{} //empty

我想找到有效的方法来做到这一点?我不是要求代码我可以在这里使用任何算法,如DP指数搜索?

2 个答案:

答案 0 :(得分:3)

由于它已经排序,您可以通过在整个数组上使用二进制搜索,轻松找到大于或等于所需最小值的最低元素。

二进制搜索在每次迭代时基本上将serch空间减少一半。给出10的第一个示例,您可以使用12上的中点开始如下:

 0  1  2  3  4  5  6  7 <- index
 4  7  9 12 23 34 56 78
         ^^

由于您正在查看的元素高于10而下一个元素较低,因此您已找到它。

然后,您可以使用类似的二进制搜索,但只能使用您刚刚找到的元素的那一部分。这次你正在寻找小于或等于所需最大值的最高元素。

在前面提到的相同示例中,您从:

开始
 3  4  5  6  7 <- index
12 23 34 56 78
      ^^

由于它小于65而且以下也是,你需要将指针增加到34..78的中间点:

 3  4  5  6  7 <- index
12 23 34 56 78
         ^^

而且你有它,因为这个数字较少而且以下数字更多(超过65)

然后你可以从停止索引(3和6)开始提取值。

 0  1  2    3  4  5  6    7 <- index
 4  7  9 ((12 23 34 56)) 78
           -----------

算法的时间复杂度为O(log N)。但请记住,这在处理更大的数据集时才变得非常重要。如果你的数据集只包含大约8个元素,你也可以使用线性搜索,因为(1)它更容易编写; (2)时差与无关。

我倾向于不担心时间复杂性,除非操作非常昂贵,数据集大小达到数千,或者我不得不每秒进行数千次。

答案 1 :(得分:2)

因为它已经排序,所以应该这样做:

List<Integer> subarray = new ArrayList<Integer>();

for (int n : numbers) {
    if (n >= MIN && n <= MAX) subarray.add(n);
}

这是O(n),因为你只看一次每个数字。