【问题标题】:ascending order check recursively递归升序检查
【发布时间】:2021-12-27 19:57:02
【问题描述】:

我尝试做的是通过分而治之的方法检查给定数组是否按升序排列。

我想知道附加返回案例 (a⌊n/2⌋−1 ≤ a⌊n/2⌋) 背后的逻辑是什么来达到最终结果。我试图在不查看解决方案的情况下解决问题,但我无法弄清楚作者是如何发现/设计a⌊n/2⌋−1 ≤ a⌊n/2⌋ 案例的。我真的很难发掘这个案子。

实际上,为什么不改用a⌊n/2⌋ ≤ a⌊n/2⌋+1 而基本情况,为什么当我从基本情况(即h<l)中删除相等性时我会出现堆栈溢出?

通过反复试验的方法,我尝试编写以下内容。

def co(a, l, h):
  if h <= l:
    return True
  mid = l + ((h-l)//2)
  cl = co(a, l, mid-1)
  rl = co(a, mid+1, h)
  return rl and cl and a[mid] < a[mid+1] 

    # how  is a[mid] < a[mid+1] devised ??
    # why not a[mid-1] < a[mid] ??

  

#c = [3, 5, 7, 9, 11,12]
c = [3, 5]


print(co(c, 0, len(c) - 1))

【问题讨论】:

  • n 是数组的长度(或当前问题的大小)。对于最小的相关案例n = 2,索引n//2 + 1 将超出范围,但n//2 - 1 不会。
  • 你写:“我试着写以下”,但是在那个代码中你写“a[mid] ....那么,你是不是写了代码,然后问我们你写了什么?

标签: algorithm recursion math divide-and-conquer off-by-one


【解决方案1】:

还有基本情况,为什么我在删除相等时会出现堆栈溢出 从基本情况来看,即 h

假设c=[3, 5]。如果你用h&lt;l替换h&lt;=l,那么当你计算co(a, 1, 1),然后mid = 1+0 ...然后rl = co (a, 1+1, 1)a[2]给你stackoverflow。

a[mid] &lt;= a[mid+1] 是如何设计的??

  • 你需要比较 subproblem1 的最右边的元素和 subproblem2 的最左边的元素。在 subproblem1 和 subproblem2 中没有考虑这两个元素的顺序

  • 小心使用 Python 索引。 1) 当您将列表拆分为a[l:mid-1]a[mid+1,h] 时,您会忽略a[mid-1]a[mid]。 2) 当你写co(c, 0, len(c) - 1) 时,你会省略c 的最后一个元素(见评论4)。

你的代码有一些错误,看我的cmets。

def co(a, l, h):
  if h <= l:
    return True
  mid = l + ((h-l)//2)
  cl = co(a, l, mid-1)
  rl = co(a, mid+1, h)
  return rl and cl and a[mid] < a[mid+1] ### Comment1: this misses checking a[mid-1] <= a[mid]

    # how  is a[mid] < a[mid+1] devised ??  ### Comment2: you should use <= rather than <
    # why not a[mid-1] < a[mid] ??
 

#c = [12, 3, 5, 7, 9, 11,12]  ### Comment3: your code returns True for this unordered list!
#c = [3, 5, 7, 9, 11,12]
c = [3, 5]


print(co(c, 0, len(c) - 1))  ### Comment4: len(c)-1 should be len(c) otherwise it's not the whole list

下面,我修复了代码中的列表索引。请注意,测试变为 h &lt;= l+1,因为在 Python 中列表 a[mid:mid+1] 包含一个元素。

def co(a, l, h):
  if h <= l+1:
    return True
  mid = l + ((h-l)//2)
  cl = co(a, l, mid)
  rl = co(a, mid, h)
  return rl and cl and a[mid-1] <= a[mid]

【讨论】:

    猜你喜欢
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 2016-12-29
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多