【问题标题】:Finding array indicies for "divide-and-conquer" algorithm?寻找“分而治之”算法的数组索引?
【发布时间】:2015-05-03 15:50:05
【问题描述】:

我必须在 C++ 中为 max 函数实现分治算法,该函数返回数组中的最大值。我了解算法并且已经设计了函数,但是我遇到了数组索引的问题。

在伪代码中,这是我的函数:

def max(array, startIndex, endIndex)

    // if there is only one element, return it
    if startIdx = endIdx
        return array[startIdx];

    leftHigh = max(array, startIdx, endIdx/2);
    rightHigh = max(array, endIdx/2 + 1, endIdx);

    return maximum of leftHigh and rightHigh;

但是,我遇到了递归调用参数的这些值的问题。以下段落展示了我在脑海中逐步浏览算法时发现的内容:

最简单的情况是一个包含 4 个元素的数组。对max 的第一次调用将采用索引参数0, 3,并将使用参数0, 12, 3 进行调用。第一次递归调用将导致使用0, 01, 1 的调用将正确终止。但是,第二次递归调用将导致调用2, 12, 3。第一个最终导致超出数组边界,第二个导致无限循环,因为这些参数已被使用。

我试过弄乱它,例如将(startIdx, endIdx/2 -1) 用于第一个边界,将(endIdx/2, endIdx) 用于第二个边界,这修复了递归调用的第二个分支,但搞砸了第一个。

有没有办法找到导致正确行为的这些索引?感谢您的帮助。

【问题讨论】:

  • A 和 B 之间的中点不是 B/2。它必须以某种方式依赖于 A。

标签: arrays algorithm recursion divide-and-conquer


【解决方案1】:

应该是

leftHigh = max(array, startIdx, (startIdx + endIdx)/2);
rightHigh = max(array, (startIdx + endIdx)/2 + 1, endIdx);

【讨论】:

    【解决方案2】:

    如果我给你两个数字:a

    a < b < c
    0 < b - a < c - a
    

    您正在选择 b = c/2。我们可以看到在某些情况下只满足上述条件:

                    b = c / 2
    and             b > a
    then            c / 2 > a
    

    所以我们可以看到,只要 a > c/2,您的方法就可以工作。在您的情况下,a = startIdx 和 c = endIdx,因此您的算法仅在 startIdx

    仔细考虑这个发现:

    a < b < c
    0 < b - a < c - a (subtract a from all parts)
    

    如果 b 介于 a 和 c 之间,那么它的值是多少?在这种情况下,(b - a) 与 (c - a) 有什么关系?

    【讨论】:

      【解决方案3】:

      Python 中的建议解决方案:

      from math import floor, ceil
      def maximum(arr, left, right):
          if left >= right:
              if left < len(arr):
                  return arr[left]
              else:
                  return arr[right]
          else:
              left = maximum(arr, left, int((left+right)/2)) # pay attention to the midpoint!
              right = maximum(arr, int((left+right)/2), right)
              return max(left, right)
      
      print maximum([1,8,2,9,3,15,5,3,2], 0, 8)
      

      输出

      15
      

      【讨论】:

        猜你喜欢
        • 2018-10-16
        • 1970-01-01
        • 2013-02-02
        • 2016-03-11
        • 1970-01-01
        • 2012-01-01
        • 2011-12-31
        • 2015-04-08
        相关资源
        最近更新 更多