【发布时间】: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 钉子:
- 首先计算此范围内的钉子可以覆盖的最小值和最大值(
min_cover和max_cover)。 - 接下来,它查看 A 和 B,并检查每个木板是否可以被
(min_cover, max_cover)范围内的任何钉子钉住。 - 如果结果是
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