【问题标题】:Algorithm for searching a value in two arrays在两个数组中搜索值的算法
【发布时间】:2017-10-20 14:34:08
【问题描述】:

任务: A 和 B 是自然数数组。 A 是一个递增排序的数组,B 是一个随机排序的数组。 K 是任意的自然数。找到一个有效的算法来确定所有可能的索引对 (i,j),使得 A[i]+B[j]=K。

这个算法效率最高吗?

public static void main(String[] args) {
            int A[] = { 1, 2, 3, 4, 6, 7, 8, 11, 13, 124};
            int B[] = {4, 1, 10, 5};
            int k = 10;
            int i = 0, n = A.length, m = B.length;
            ArrayList<String> result = new ArrayList<String>();
            while (i < n){
                if (A[i] >= k) {
                    break;
                }else {
                    int j = 0;
                    while(j < m) {
                        if (A[i] + B[j] == k) {
                            result.add("i = " + i + " j = " + j);
                        }
                        j++;
                    }
                }
                i++;
            }
            for(int z = 0; z < result.size(); z++) {
                System.out.println(result.get(z));
            }
}

【问题讨论】:

  • 数组A中的数字是不同的吗?
  • 迭代 B 中的数字,并为 B 中的每个 b,二进制搜索 A 中的 k-b。
  • "这种算法是最有效的吗" 不,你可以从 A 表的中间开始。然后根据 A[i] + B[j] 的结果向下或向上。那会更有效率,所以它不可能是最有效的。 编辑:实际上这就是@tobias_k 的提议

标签: java algorithm


【解决方案1】:

不,算法不是很有效。虽然您在break 中找到大于kA 中的a,但您仍然需要在此之前测试ab 的所有组合,从而使您的算法复杂度为O(m n),其中 n 是 A 中的元素数,m 是 B 中的元素数。

相反,我建议如下:

  • 循环遍历b 中的所有元素B
  • 确定a = K - b
  • 使用binary search查找aA中的索引,如果存在的话
  • 如果a存在于A中,则打印ab的索引

这利用了由于A 已排序的事实,我们可以快速确定对于给定的b,是否有a 使得a + b = k 存在于A 中。反过来是不可能的,因为B 是随机排序的。总复杂度为 O(m log n)。

【讨论】:

  • 更多优化:首先,在A 中对k 进行二分搜索,然后将该索引用作所有其他二分搜索的上限,如果是b &gt; k,则不要根本不搜索。
  • 这个答案只有在A中没有重复的时候才是正确的。
  • @DAle 这是一个很好的观点。您仍然可以使用二分搜索,但从找到的索引中,您还必须检查并打印上一个和下一个索引,直到找到不同的a
  • 在最坏的情况下,AB 包含单个值 ab,这样 a+b=K。打印所有匹配的索引对至少需要(n*m) 操作。所以没有算法可以通过O(n*m)
  • @fjardon 是的,在实际上有 n * m 个解决方案的极端情况下,该算法将花费 n * m 时间,但在一般情况下,没有或几乎没有重复,复杂度仍应为 O(mlogn)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
相关资源
最近更新 更多