【问题标题】:Codility NailingPlanks - Using Binary Search on Nail Count Instead of PlanksCodility NailingPlanks - 对钉子数使用二进制搜索而不是木板
【发布时间】:2022-01-02 23:26:32
【问题描述】:

我已经阅读了这个问题的答案 - Codility NailingPlanks。 这不是重复的,因为我正在尝试使用不同的方法来解决这个问题 - 我不是在给定钉子可以覆盖的木板上运行二进制搜索,而是尝试在所需的钉子总数上运行它覆盖所有的木板。

这是我的代码:

def solution(A, B, C):
    min_nails = 1
    max_nails = len(C)
    valid = []
    while (min_nails <= max_nails):
        mid_nails = (min_nails + max_nails) // 2
        if (is_valid_nails_amount(mid_nails,A,B,C)):
            max_nails = mid_nails - 1
            valid.append(mid_nails)
        else: 
            min_nails = mid_nails + 1
    return -1 if len(valid) == 0 else min(valid)

def is_valid_nails_amount(nails,A,B,C): 
    candidates=C[0:nails]
    min_cover = min(candidates)
    max_cover = max(candidates)
    isValid = True
    for (a,b) in zip(A,B): 
        if not(min_cover in range(a, b + 1) or max_cover in range(a, b + 1) or a in range(min_cover, max_cover + 1) or b in range(min_cover, max_cover + 1)): 
            isValid = False
            break 
    return isValid

算法首先检查 C 中的第一个 len(C) + 1 / 2 钉子:

  1. 首先计算此范围内的钉子可以覆盖的最小值和最大值(min_covermax_cover)。
  2. 接下来,它查看 A 和 B,并检查每个木板是否可以被(min_cover, max_cover) 范围内的任何钉子钉住。
  3. 如果结果是False,我们将min_nails 更新为mid_nails + 1 并重复。如果结果是True,我们将钉子的数量存储在valid 数组中,并尝试通过设置max_nails = mid_nails - 1 来找到同样有效的钉子数量

这种方法获得 100% 的正确性,但是在性能测试中失败,因为它产生了不正确的结果 - 对于每个性能测试,钉子的最小数量obtained 远低于预期结果。我怀疑错误会在这一行:if not(min_cover in range(a, b + 1) or max_cover in range(a, b + 1) or a in range(min_cover, max_cover + 1) or b in range(min_cover, max_cover + 1))

但我不知道它是什么。

【问题讨论】:

  • [mincover,maxcover] 重叠 [a,b] 确实暗示有钉子实际击中木板。如果最高和最低的指甲是数字 0 和 1 怎么办?你永远不会返回超过 2 个。
  • 还有其他问题。您确定 in range(...) 不会迭代吗?二进制搜索不太正确。你不应该复制指甲列表来制作“候选人”
  • 如果最低的钉子是0,最高的钉子是1,那是不是意味着它应该覆盖[0,1]范围内的所有木板?
  • 位置 1 和 4 的钉子没有钉板 [2,3]

标签: python algorithm binary-search


【解决方案1】:

您的if 条件的问题可以通过此示例输入看到:

A = [1,3,5]
B = [2,4,6]
C = [1,5,3]
print(solution(A, B, C))

这将打印 2,但预期的输出是 3,因为需要所有三个钉子。

然而,您的代码将有 is_valid_nails_amount(2, A, B, C) 返回 True,尽管第二块木板没有被那两个钉子钉住。

问题是这些条件都不能保证钉子会碰到木板(a, b)

a in range(min_cover, max_cover + 1)
b in range(min_cover, max_cover + 1)

您的算法确实需要检查在该最小/最大范围内是否有可用于击打木板的钉子。

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多