鱼C论坛

 找回密码
 立即注册
查看: 2991|回复: 40

[已解决]Python:每日一题 280

[复制链接]
发表于 2019-11-25 20:50:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zltzlt 于 2019-11-25 20:53 编辑

今天的题目:


给定一个数组 num 和一个整数 target,找到 num 中所有的数字之和为 target 的组合

注意:组合在原列表中可以是不连续的。

示例 1:

输入:num = [7,1,2,5,1,6,10], target = 8
输出:[[1,1,6],[1,2,5],[1,7],[2,6]]
示例 2:

输入:num = [1,1,1], target = 2
输出:[[1,1]]
解释:组合列表中不能包含重复的组合。


欢迎大家一起答题!
最佳答案
2019-11-25 23:18:16
但愿别超过最大递归深度
另外,真的不要求列表顺序哦?
  1. def solve(num:list,target:int)->list:
  2.     num = sorted(num,reverse=True)
  3.     res = []
  4.     for i in range(len(num)):
  5.         if target > num[i]:
  6.             now = [num[i]]
  7.             get = solve(num[i+1:],target - num[i])
  8.             #print('调试',num[i],target,get,num,now,res)
  9.             for each in get:
  10.                 each.extend(now)
  11.                 res.append(each[:]) if each not in res else ''
  12.         elif target == num[i]:
  13.             res.append([num[i]]) if [num[i]] not in res else ''
  14.     return res

  15. if __name__ == '__main__':
  16.     print('示例1 输出:',solve([7,1,2,5,1,6,10],8))
  17.     print('示例2 输出:',solve([1,1,1],2))
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-11-25 21:50:03 | 显示全部楼层
本帖最后由 凌九霄 于 2019-11-25 21:54 编辑

#list不大的话,可以凑合用下
  1. import itertools


  2. def func280(L, n):
  3.     t, result = [], []
  4.     for i in range(1, len(L) + 1):
  5.         t.extend(map(tuple, map(sorted, itertools.combinations(L, i))))

  6.     for i in set(t):
  7.         if sum(i) == n:
  8.             result.append(list(i))
  9.     return result
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-25 21:55:34 From FishC Mobile | 显示全部楼层
除了全排列之外想不出更高效的方法。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-25 22:03:44 | 显示全部楼层
本帖最后由 danteer 于 2019-11-26 21:28 编辑
  1. import itertools

  2. def func(num,target):
  3.     if num == []:
  4.         return []
  5.     result = []
  6.     num.sort()
  7.     position = len(num)
  8.     for i in range(len(num)):
  9.         if num[i] > target:
  10.             position = i
  11.             break
  12.     num = num[:position]
  13.     count = 1
  14.     while sum(num[:count]) <= target:
  15.         temp = list(itertools.combinations(num,count))
  16.         for each in temp:
  17.             if sum(each) == target:
  18.                 if not list(each) in result:
  19.                     result.append(list(each))
  20.         count += 1
  21.     return result
复制代码

上面的大概超时,试试下面的吧 。。。
  1. import sys
  2. sys.setrecursionlimit(922337580)

  3. def solve(num,target):
  4.     if num == []:
  5.         return []
  6.     result = []
  7.     num.sort()
  8.     position = len(num)
  9.     for i in range(len(num)):
  10.         if num[i] > target:
  11.             position = i
  12.             break
  13.     num = num[:position]
  14.     count = 1
  15.    
  16.     def sumplus(course):
  17.         temp = 0
  18.         for each in course:
  19.             temp += num[each]
  20.         return temp
  21.    
  22.     def move(x,target,count,course):
  23.         if x != len(course)-1:
  24.             if course[x+1] != course[x] + 1:
  25.                 course[x] += 1
  26.                 for each in range(x+1,len(course)):
  27.                     course[each] = course[x] + each - x
  28.                 move(len(course)-1,target,count,course)
  29.             else:
  30.                 course[x] += 1
  31.                 for i in range(x+1,len(course)):
  32.                     course[i] = course[x] + i - x
  33.                 move(x+1,target,count,course)
  34.             
  35.         else:
  36.             ccc = sumplus(course)
  37.             if ccc == target:
  38.                 listtemp = []
  39.                 for each in course:
  40.                     listtemp.append(num[each])
  41.                 if not listtemp in result:
  42.                     result.append(listtemp)
  43.                 if course[0] != len(num) - count:
  44.                     if course[x] != len(num) - 1:
  45.                         course[x] += 1
  46.                         move(x,target,count,course)
  47.                     else:
  48.                         if len(course) > 1:
  49.                             move(x-1,target,count,course)
  50.                         else:
  51.                             pass
  52.                 else:
  53.                     pass
  54.             elif ccc < target:
  55.                 if course[-1] != len(num) - 1:
  56.                     course[-1] += 1
  57.                     move(x,target,count,course)
  58.                 else:
  59.                     if course[0] == len(num) - count:
  60.                         pass
  61.                     else:
  62.                         for i in range(len(course)-2,-1,-1):
  63.                             if course[i] != len(num) - count + i:
  64.                                 temp = i
  65.                         move(temp,target,count,course)
  66.             elif ccc > target:
  67.                 if course[0] == len(num) - count:
  68.                     pass
  69.                 else:
  70.                     temp = -10
  71.                     for i in range(len(course)-2,-1,-1):
  72.                         if course[i] != len(num) - count + i:
  73.                             if temp == -10:
  74.                                 temp = i
  75.                     if temp == -10:
  76.                         pass
  77.                     else:
  78.                         move(temp,target,count,course)

  79.            
  80.                  
  81.     def comb(num,count,target):
  82.         course = []
  83.         for i in range(count):
  84.             course.append(i)
  85.         if sum(num[:count]) == target:
  86.             temp2 = []
  87.             for each in course:
  88.                 temp2.append(num[each])
  89.             result.append(temp2)
  90.         move(len(course)-1,target,count,course)
  91.    
  92.     while sum(num[:count]) <= target:
  93.         comb(num,count,target)
  94.         count += 1
  95.     return result
复制代码

超过最大递归深度了,白给
还是itertools好用

评分

参与人数 1贡献 +1 收起 理由
zltzlt + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-25 23:18:16 | 显示全部楼层    本楼为最佳答案   
但愿别超过最大递归深度
另外,真的不要求列表顺序哦?
  1. def solve(num:list,target:int)->list:
  2.     num = sorted(num,reverse=True)
  3.     res = []
  4.     for i in range(len(num)):
  5.         if target > num[i]:
  6.             now = [num[i]]
  7.             get = solve(num[i+1:],target - num[i])
  8.             #print('调试',num[i],target,get,num,now,res)
  9.             for each in get:
  10.                 each.extend(now)
  11.                 res.append(each[:]) if each not in res else ''
  12.         elif target == num[i]:
  13.             res.append([num[i]]) if [num[i]] not in res else ''
  14.     return res

  15. if __name__ == '__main__':
  16.     print('示例1 输出:',solve([7,1,2,5,1,6,10],8))
  17.     print('示例2 输出:',solve([1,1,1],2))
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 00:05:52 From FishC Mobile | 显示全部楼层
本帖最后由 peicd 于 2019-11-26 00:07 编辑

貌似有几位大佬假定list和target全为正整数,但题目并没有说正整数,负数也有可能哦。

评分

参与人数 1荣誉 +1 收起 理由
haoqianga + 1 无条件支持楼主!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 00:06:58 | 显示全部楼层
peicd 发表于 2019-11-25 21:55
除了全排列之外想不出更高效的方法。

应该想,怎么去优化全排
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 00:14:20 | 显示全部楼层
你们都好聪明啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 00:45:05 | 显示全部楼层
本帖最后由 Stubborn 于 2019-11-26 00:49 编辑

需要测试很大的数组吗?

  1. def fun280(nums:List[int], target:int) ->List:
  2.     if not nums: return []
  3.     length = len(nums)
  4.     nums.sort()
  5.     result = []
  6.     def combination(pointer:int, item:list, target:int):
  7.         if target == 0:
  8.             result.append(item)
  9.             return
  10.         if pointer == length or target < nums[pointer]:return
  11.         for index in range(pointer, length):
  12.             if index > pointer and nums[index] == nums[index-1]:continue
  13.             combination(index+1, item+ [nums[index]], target-nums[index])
  14.     combination(0, [], target)
  15.     return result
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 04:04:45 | 显示全部楼层
  1. import itertools

  2. def check(lst, target):
  3.         result = []
  4.         length = len(lst)
  5.         for num in range(2,length):
  6.                 temp = itertools.combinations(lst, num)
  7.                 for each in temp:
  8.                         each = list(each)
  9.                         each.sort()
  10.                         if sum(each) == target and not each in result:
  11.                                 result.append(each)
  12.         return result
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 09:47:15 | 显示全部楼层
想了好久不知道问题在哪。请大佬斧正
  1. from itertools import combinations as cb


  2. def listzzj(qj, mbz):
  3.     for i in range(1, len(qj) + 1):
  4.         zzj = list(cb(qj, i))
  5.         for x in zzj:
  6.             if sum(x) == mbz:
  7.                 return x
  8.                

  9. num = [7,1,2,5,1,6,10]
  10. target = 8
  11. listzzj(num, target)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:30:00 | 显示全部楼层
本帖最后由 凌九霄 于 2019-11-26 10:31 编辑
dzqzzzh 发表于 2019-11-26 09:47
想了好久不知道问题在哪。请大佬斧正


你在迭代内使用return会终止迭代,所以最终只能得到第一个符合条件的结果
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:32:01 | 显示全部楼层
dzqzzzh 发表于 2019-11-26 09:47
想了好久不知道问题在哪。请大佬斧正

起码得把比target大得数给去掉? 刚刚有人说可能有负数,还是不能去
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:35:08 | 显示全部楼层
dzqzzzh 发表于 2019-11-26 09:47
想了好久不知道问题在哪。请大佬斧正

你是只求一个就返回,这是个问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:39:33 | 显示全部楼层
dzqzzzh 发表于 2019-11-26 09:47
想了好久不知道问题在哪。请大佬斧正

还有没考虑是组合,不是排列,没有去重
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:48:46 | 显示全部楼层
dzqzzzh 发表于 2019-11-26 09:47
想了好久不知道问题在哪。请大佬斧正

from itertools import combinations as cb


def listzzj(qj, mbz):
    xs=[]
    for i in range(1, len(qj) + 1):
        zzj = list(cb(qj, i))
        for x in zzj:
            if sum(x) == mbz:
                x=sorted(x)
                if x not in xs:
                    xs.append(x)

    return xs

num = [7, 1, 2, 5, 1, 6, 10]
target = 8
print(listzzj(num, target))
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 10:52:21 | 显示全部楼层
每日一题这个系列在哪个板块找到
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 16:51:46 | 显示全部楼层
  1. from itertools import combinations

  2. def fun280(num,target):
  3.     result = []
  4.     for i in range(1,len(num)+1):
  5.         for j in combinations(num,i):
  6.             if sum(j) == target and sorted(list(j)) not in result:
  7.                 result.append(sorted(list(j)))
  8.     return result
复制代码

评分

参与人数 1贡献 +1 收起 理由
zltzlt + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-26 18:50:55 | 显示全部楼层
from itertools import combinations

def fun280(num,target):
    result = []
    for i in range(1,len(num)+1):
        for j in combinations(num,i):
            if sum(j) == target and sorted(list(j)) not in result:
                result.append(sorted(list(j)))
    return result

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-26 20:47:07 | 显示全部楼层
本帖最后由 zltzlt 于 2019-11-26 20:56 编辑
凌九霄 发表于 2019-11-25 21:50
#list不大的话,可以凑合用下


输入 num = [29,19,14,33,11,5,9,23,23,33,12,9,25,25,12,21,14,11,20,30,17,19,5,6,6,5,5,11,12,25,31,28,31,33,27,7,33,31,17,13,21,24,17,12,6,16,20,16,22,5], target = 28 超时
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-21 18:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表