【问题标题】:Binary search in 2 dimensional array with duplicates Java具有重复Java的二维数组中的二进制搜索
【发布时间】:2012-01-04 07:34:34
【问题描述】:

设计一个算法,FindElement(a,p),其中“a”是具有重复的正整数的二维方阵,并且每行整数都按非降序排列: a[i][0]≤a[i][1]≤a[i][2]···≤a[i][n-1] (i=0,1,. . .,n-1),.该算法应定义 p 是否包含在 a 中。如果“p”成立,它应该返回 true,否则返回 false。 您的算法必须尽可能高效。算法应该基于二分查找

我找到了以下解决方案(但我不确定它是否正确):

解决方案是使用二进制搜索一次搜索在一行上工作的元素。对大小为 (n) 的给定排序行进行二进制搜索需要 O(Log(n)),因此在最坏的情况下搜索整个数组需要 O(nlog(n))。

这个解决方案是否适合给定的任务?我不知道如何实现这个算法,请你给我伪代码或解释如何做到这一点。 提前致谢。

【问题讨论】:

  • 不清楚 1.你是搜索等于p的元素还是什么? 2. 如果有重复,输出是什么?所有事件的索引? 3. 你真的需要对这个任务使用二分查找吗(如果允许分配哈希表,有一个更有效的方法来实现这个请求)。请澄清问题陈述。
  • 实际上,“方形/二维数组”是一个红鲱鱼 - 你在概念上(可能)有其他东西,允许在O(log n) 中执行整个搜索。当前的答案都没有提到这种可能性(不过@Amit 很接近)。这不需要分配哈希表,或者实际上除了用于O(n log n) 搜索的变量之外的任何其他变量 - 您只需换个角度思考。我没有透露实际答案,因为我希望你考虑一下。哦,你没有提到你是否需要所有次出现,或者只需要一次(结果完全不同)。
  • 使用完美哈希的搜索平均为您提供 O(1)(加上此特定情况的输出长度)。
  • 好吧,我有点误读了规范。我概述的解决方案仅在所有情况下 a[i][n-1] ≤ a[i+1][0] 时才有效,此处可能不是。否则,您提出的解决方案应该可以正常运行。

标签: java algorithm search


【解决方案1】:

是的,您的解决方案似乎正确且有效(鉴于您对初始问题的描述,他们可能希望您使用二进制搜索)。你的算法应该是这样的:

public Point FindElement(int[][] matrix, int number) {
    Point p = new Point(); // holds two integers and represents 
                           // a position in the matrix.
    int found = -1;
    for(int i = 0; i < N; i++) {
        found = binarySearch(matrix[i], number, 0, N);
        if(found != -1) { 
           p.setX(i); 
           p.setY(found); 
           return p; 
        }
    }
    return null;
}

这里可以根据伪代码实现二分查找:http://en.wikipedia.org/wiki/Binary_search_algorithm#Recursive

【讨论】:

  • 假设输出您找到的第一个匹配项没问题,上述解决方案有效,但您可能需要同时返回 i 和 found 以便获得匹配项的行和列。此外,如果允许,请使用 Arrays.binarySearch() 而不是自己编写。
  • 是的,你是对的。 Arrays.binarySearch() 存在,但考虑到它是家庭作业,他们可能想要一个完整的实现。
  • 对不起,我不明白你是如何遍历二维数组的所有行的?你正在经历这个循环:for(int i = 0; i
  • "matrix" 是输入的二维数组,如您的描述中的“a”。
【解决方案2】:

是的解决方案是正确的。

这是伪代码

     int index = -1;
    for (int i : height of array){
      int[] putIn1Darray = a[i][j] where j = 0 to n;
      index = Arrays.binarySearch(putIn1Darray,p); 
      if (index == -1)
          //Element not found yet
          continue;
      else
          //Element found
          break;   
    } 
    print index;

上述算法用于显示元素p的第一次出现。

您可以根据自己的硬件对其进行修改。

【讨论】:

    【解决方案3】:

    二分查找仅适用于排序列表。所以如果合适的话:我会说是的。只要确保在得到所有重复的答案时向前和向后走。

    您可以以此为基础: http://www.java-tips.org/java-se-tips/java.lang/binary-search-implementation-in-java.html

    【讨论】:

      【解决方案4】:

      在现实生活中,如果我能保证数据已排序,我会使用 java.util.Arrays.binarySearch。我使用 Arrays.sort 函数对数组进行排序或使用 TreeMap/TreeSet 加载数据并使用 get 函数。

      【讨论】:

        【解决方案5】:

        如果我正确理解了您的问题描述,那么您在各个行之间没有任何关系/约束,对吧?只有单行中的元素按升序排序。

        如果您需要进行大量搜索,只需将矩阵作为列表读取并再次排序即可。这需要大约 N^2*log(N) 的时间。之后,只需对该折叠列表进行二进制搜索,该列表将再次按照 log(N) 的顺序为 log(N^2) = 2*log(N)。

        可以将预处理纳入搜索时间的收支平衡点是当您搜索至少 N 次时。

        【讨论】:

          【解决方案6】:

          我是这样看待这个问题的:

          有蛮力方式、半蛮力方式和高效方式。 我没有看到这里列出的有效方法。

          假设它是一个方阵,n = 行数/列数

          1. 蛮力方式是线性搜索一切,O(n^2),

          2. 您的方法(连同列出的其他答案),O(n log n),

          3. 更有趣的答案,二维二分搜索。

          假设您有一个在矩阵中搜索值的函数,

          boolean findInMatrix(a, p)
          {       
              if(a == null) 
                  return false;
              //Compare the middle of the matrix with p
          
              if(p == a[n/2][n/2])
                  return true;        
          
              if(a.length == 1)
                  return false;       
          
              if p < a[n][n], then 
                  return findInMatrix(top left, p) || findInMatrix(bottom left, p) || findInMatrix(top right, p);
              else 
                  return findInMatrix(bottom right, p) || findInMatrix(bottom left, p) || findInMatrix(top right, p);
          }
          

          砰,完成。当然,您需要处理如何传入部分矩阵进行搜索,您可以通过传入 2D 范围使用就地方法,也可以复制矩阵。 如您所见,每次迭代都是二进制搜索 x 3。复杂度仍应为 O(log N),其中 N 是单元格总数,n^2。

          这个解决方案启发我的是,我认为我们应该充分利用给定的属性,而不是仅仅使用一半的一维排序搜索。

          如果我的解决方案有误,请告诉我。

          注意:糟糕,我将问题误读为 Clockwork-Muse。此解决方案不适用于该问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-16
            • 1970-01-01
            • 2015-03-21
            相关资源
            最近更新 更多