在一系列重复元素中找到第一个元素的最快方法

时间:2015-08-11 23:34:03

标签: algorithm scala

我编写了这个二进制搜索函数来定位索引序列中的特定值:

  def locate(xs: IndexedSeq[Int], x: Int, l: Int, h: Int): Int = {
    (l + h) / 2 match {
      case m if h - l <= 1 => l
      case m if x >= xs(m) => locate(xs, x, m, h)
      case m => locate(xs, x, l, m)
    }
  }

当我有一个如下序列时,它会起作用:

Vector(1,2,3,9,15,26,89)

即,有序的独特元素序列。但是当有序序列中存在重复元素时,它不起作用,如:

Vector(1,2,3,3,15,15,89)

无法保证选择重复子序列的第一个元素。例如,如果我想搜索3,它可能不会给我序列中前3个的索引。

哪种算法可以有效地做到这一点?或者我可以修改我的二进制搜索序列,以便我轻松实现这一目标(同时仍然是尾递归)。

1 个答案:

答案 0 :(得分:1)

基于C++'s lower_bound的算法,我认为这种改变就足够了:

def locate(xs: IndexedSeq[Int], x: Int, l: Int, h: Int): Int = {
    l+(h-l)/2 match {
        case m if h - l == 0 => l
        case m if xs(m) < x => locate(xs, x, m+1, h)
        case m => locate(xs, x, l, m)
    }
}

我还更改了m的计算代码,因为在极端情况下原始代码容易出现整数溢出。