【问题标题】:Find all differences in sorted array查找排序数组中的所有差异
【发布时间】:2018-07-28 17:52:01
【问题描述】:

我有一个已排序(升序)的实数值数组,称之为 a(可能重复)。我希望在给定一系列值 [x, y] 的情况下,找到存在索引 j 的值 (i) 的所有索引,使得: j>i 和 x

输出是一个长度为 a.Length 的布尔数组。 由于数组对所有前向差异进行排序,因此 x 和 y 是正数。

我设法做的最好的事情是从每个索引开始查看它前面的子数组,然后对 x+a[i] 执行二进制搜索并检查 a[j]

我应该注意,最终我想在同一个数组 a 上执行许多这样的范围 [x,y] 的搜索,但是范围的数量远远小于数组的长度(4-6 个幅度更小) - 因此我更关心搜索的复杂性。

例子:

a= 0, 1, 46, 100, 185, 216, 285

范围 x,y=[99,101] 应该返回:

[true, true, false, false, true, false, false]

只有值 0,1 和 185 在该范围内具有正向差异。

内存中的代码,可能有一些错误:

int bin_search_closesmaller(int arr[], int key, int low, int high)
{
    if (low > high) return high;
    int mid = (high - low)/2;
    if (arr[mid] > key) return bin_search_closesmaller(arr, key, low, mid - 1);
    if (arr[mid] < key) return bin_search_closesmaller(arr, key, mid + 1, high);
    return mid;
}

bool[] findDiffs(int[] a, int x, int y)
{
    bool[] result = new bool[a.Length];
    for(int i=0; i<a.Length-1;i++)
    {
        int idx=bin_search_closesmaller(a, y+a[i], i+1, a.Length-1);
        if (idx==-1) continue;
        if (a[idx]-a[i] >= x) result[i]=true;
    }
}

谢谢!

【问题讨论】:

  • 你能添加一个示例数组和范围吗?
  • The best I’ve managed to do - 你能展示你的尝试吗?这是一个有趣的问题,由于问题中缺少代码,我不想看到它关闭。
  • @NightOwl888 我添加了我的尝试

标签: c# arrays algorithm binary-search


【解决方案1】:

只要对输入数组进行排序,问题就存在线性解。关键是使用两个索引来遍历数组a

bool[] findDiffs(int[] a, int x, int y)
{
  bool[] result = new boolean[a.Length];
  int j = 0;

  for (int i = 0; i < a.Length; ++i) {
    while (j < a.Length && a[j] - a[i] < x) {
      ++j;
    }
    if (j < a.Length) {
      result[i] = a[j] - a[i] <= y;
    }
  }

  return result;
}

使用a = [0,100,1000,1100](x,y) = (99,100)

i = 0, j = 0 => a[j] - a[i] = 0 < x=99     => ++j
i = 0, j = 1 => a[j] - a[i] = 100 <= y=100 => result[i] = true; ++i
i = 1, j = 1 => a[j] - a[i] = 0 < x=99     => ++j
i = 1, j = 2 => a[j] - a[i] = 900 > y=100  => result[i] = false; ++i
i = 2, j = 2 => a[j] - a[i] = 0 <= x=99    => ++j
i = 2, j = 3 => a[j] - a[i] = 100 <= y=100 => result[i] = true; ++i
i = 3, j = 3 => a[j] - a[i] = 0 <= x=99    => exit loop

【讨论】:

    【解决方案2】:

    创建两个索引leftright 并遍历数组。 Right 索引移动直到超出当前left 的范围,然后检查前一个元素是否在范围内。索引只向前移动,所以算法是线性的

     right=2
     for left = 0 to n-1:
        while A[right] < A[left] + MaxRangeValue
           right++
        Result[left] =  (A[right - 1] <= A[left] + MinRangeValue)
    

    关于这个算法的另一种观点:
    - 当差值太小时,向右递增
    - 当差异太大时,向左递增

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      相关资源
      最近更新 更多