给定数组求任意个数元素和小于且最接近一个数

这篇博客探讨了如何在给定的数组中找到若干元素之和最接近但不超过特定数值的子集。例如,对于数组[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],目标是最小化与特定数值的差距。结果显示,存在多个子集如[4, 10]、[5, 9]等,它们的和为0,即与目标值最接近。" 125226239,8753306,语雀画板:从思维导图到无限创作空间,"['编辑器', '前端', 'Sass', '知识创作', '图形工具']
last = []
left = []

def sort_dict(last):         #返回字典最小value对应的item
    res = dict()
    values = list(last.values())
    keys = list(last.keys())
    min = [0]
    for index in range(len(values)):
        if values[index] < values[min[0]]:
            min.clear()
            min.append(index)
        elif values[index] == values[min[0]]:
            min.append(index)
    for index in min:
        key = keys[index]
        res[key] = last[key]
    return res

def max_num(a, n):  # 和不大于n的最大个数元素
    a.sort()
    s = 0
    index = 0
    if n < a[0]:
        return -1
    while s < n and index <len(a):
        s += a[index]
        index += 1
    return index
     
def sub_list(a, index, n):  # 生成元素个数为n的子数组
    if index == n:
        res = a[:n]
        res.sort()
        global last
        if res not in last:
            last.append(res)
        left_0 = a[n:]
        left_0.sort()
        global left
        if left_0 not in left:
            left.append(left_0)
    else:
        for i in range(index, len(a)):
            a[i], a[index] = a[index], a[i]
            sub_list(a, index + 1, n)
            a[index], a[i] = a[i], a[index]

def main(a, n):   
    result = dict()
    mx = max_num(a, n)
    if mx == len(a):
        result[str(a)] = n - sum(a)
        return result
    if mx ==-1:
        return {}
    for i in range(1, mx+1):
        sub_list(a, 0, i)
    global last
    global left
    for i in range(len(last)):
        if sum(last[i]) + min(left[i]) > n and sum(last[i]) <= n:    # 筛选标准
            result[str(last[i])] = n - sum(last[i])
        else:
            pass
    return sort_dict(result)

a= [1,2,3,4,5,6,7,8,9,10]
n=120
res = main(a, n)
print(res)
n=0
res = main(a, n)
print(res)
n=14
res = main(a, n)
print(res)

结果:
{’[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]’: 65}

{}

{’[4, 10]’: 0, ‘[5, 9]’: 0, ‘[6, 8]’: 0, ‘[1, 3, 10]’: 0, ‘[1, 4, 9]’: 0, ‘[1, 5, 8]’: 0, ‘[1, 6, 7]’: 0, ‘[2, 3, 9]’: 0, ‘[2, 4, 8]’: 0, ‘[2, 5, 7]’: 0, ‘[3, 4, 7]’: 0, ‘[3, 5, 6]’: 0, ‘[1, 2, 3, 8]’: 0, ‘[1, 2, 4, 7]’: 0, ‘[1, 2, 5, 6]’: 0, ‘[1, 3, 4, 6]’: 0, ‘[2, 3, 4, 5]’: 0}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值