繁体   English   中英

Python 程序查找加起来为一个键的子列表

[英]Python program to find sub-list that adds up to a key

我被要求写一个 python function 来验证列表 l 中是否至少有一个连续的正整数序列(即一个连续的子列表),可以总结为给定的目标正数 Z157DB7DF3t60023572E515D返回包含可以找到此序列的最小开始和结束索引的字典最小列表,或者在没有此类序列的情况下返回数组 [-1, -1]。 例如,包含元素 [4, 3, 5, 7, 8] 和键 t 为 12 的列表 l,function 将返回列表 [0,2],因为该列表包含值 4,3 和5 和另一个列表 l 包含元素 [1,2,3,4] 和键 t 为 15,function 将返回 [-1,-1] 因为没有可以总结的列表 l 的子列表到给定的目标值 t = 15。我应该编写一个 function 来标识第一个给定的子列表,该子列表总和为键 t,因此它应该只返回一个子列表。 子列表只能通过以下方式识别:

  • 每个列表 l 将包含至少 1 个元素,但不会超过 100 个。
  • l 的每个元素都在 1 到 100 之间。
  • t 为正 integer,不超过 250。
  • 列表 l 的第一个元素的索引为 0。
  • 对于 solution(l, t) 返回的列表,开始索引必须等于或小于结束索引。 到目前为止,我已经能够实现前面提到的前两个示例。 这是我到目前为止所尝试的:
def solution(l, t):
    if len(l) <= 100 and len(l) > 0 and t > 0 and t <= 250:
        if all(a<100 for a in l):
            for j in range(0, len(l) - 1):
                for k in range(0, len(l)):
                    for m in range(0, len(l)):
                        if l[j] + l[k] == t or l[j] + l[k] + l[m] == t:
                            if j + 1 == k and k + 1 == m:
                                return (j, k) if l[j] + l[k] == t else (j,k, m) if l[j] + l[k] + l[m] == t else (-1,-1)
            return (-1,-1)
        else:
            return False
    else:
        return False

我的 function 只返回最多 3 个值的列表,我希望它返回任意数量的值。 请帮助我,因为这将在 4 天内到期。 非常感谢您的帮助,因为我在 python 方面的经验很少,所以请对我轻松一点。

def find_seq(inp_list,target):
    start = end = 0
    while start < len(inp_list):
        value = sum(inp_list[start:end+1])
        if value > target:
            start += 1
            if start > end and end < len(inp_list):
                end += 1
        elif value < target:
            if end < len(inp_list):
                end += 1
            else:
                return [-1,-1]
        else:
            return [start,end]
    return [-1,-1]
find_seq([4, 3, 5, 7, 8],12) # [0, 2]

由于您关注的是正整数的连续子列表,因此您可以简化问题。

我们限制自己在数字中从左到右移动,即开始/结束只能增加,不能减少。 这不应该导致我们丢失任何解决方案,因为我们可以通过从开头开始并增加所选子列表的开始/结束来到达任何可能的子列表,并且出于以下进一步解释的其他原因。

给定一个连续的子列表,您的值可能太大、太小或等于目标。 如果它等于目标,那么你就完成了。

如果它太大,那么你需要删除一些数字。 由于我们只是向右移动,因此删除数字的唯一方法是增加起点。 为了确保我们不会跳过任何解决方案,我们将 start 增加尽可能小的数量,即 1。我们不能让 start go 超出我们的子列表的末尾,所以如果 start 和 end 彼此相等,我们必须增加两者。 我们不能让结尾 go 超过输入列表的结尾,所以我们只在可以的时候增加结尾。

另一方面,如果当前子列表总和太小,我们需要添加数字。 这意味着我们需要增加末尾,这将为我们提供一个新数字以包含在总和中。 由于末尾不能 go 超过输入列表的末尾,因此我们仅在能够时才增加。 如果我们做不到,那意味着我们没有数字可以添加,我们的价值太小了。 这意味着我们永远不会达到该值,我们可以以 (-1,-1) 结果终止(没有匹配项添加到目标)。

你可能会问,为什么我们不把起点往后移呢? 好吧,如果我们这样做了,我们的值就会太大(甚至不包括输入列表中的最终数字),并且对于我们的结束索引到达末尾来说,这必须是正确的。 请记住,仅当先前的总和太大时才会增加起始索引,因此在某些时候我们会增加起始索引,因为总和太大。 自从那个决定以来,我们已经将结局向前推进,增加了更多的东西。 因此,向后移动起点会导致子列表太大。

最后,如果 start 到达输入列表的末尾,那么我们已经遍历了所有可能性,但一无所获。

从性能的角度来看,您可以通过仅跟踪一个总和值并在每次增加结束时添加新值并每次减去旧的左值来使每次循环迭代都不必对整个开始到结束子列表求和你增加开始的时间。 我没有费心去做,但你可以。

这可以解决任务:

def summing_up_target(lst, t):
    for i in range(len(lst)):
        for ii in range(i,len(lst)):
            if sum(lst[i:ii]) == t:
                return [i,ii]
            elif sum(lst[i:ii]) > t:
                break
    return [-1, -1]

summing_up_target([4, 3, 5, 7, 8], 12)

解释:

  • 您通过分割成子列表来迭代您的输入列表。
  • 如果其中一个子列表与目标匹配,则返回True ,如果子列表的总和超出target ,则移动到列表中的下一个索引并从那里继续切片

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM