Python算法题集_组合总和

 Python算法题集_组合总和

  • 题39:组合总和
  • 1. 示例说明
  • 2. 题目解析
    • - 题意分解
    • - 优化思路
    • - 测量工具
  • 3. 代码展开
    • 1) 标准求解【值传递+回溯】
    • 2) 改进版一【引用传递+堆栈回溯】
    • 3) 改进版二【过程值列表缓存+遍历后检索】
  • 4. 最优算法
  • 5. 相关资源

本文为Python算法题集之一的代码示例

题39:组合总和

1. 示例说明

  • 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

    candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

    对于给定的输入,保证和为 target 的不同组合数少于 150 个。

    示例 1:

    输入:candidates = [2,3,6,7], target = 7
    输出:[[2,2,3],[7]]
    解释:
    2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    7 也是一个候选, 7 = 7 。
    仅有这两种组合。
    

    示例 2:

    输入: candidates = [2,3,5], target = 8
    输出: [[2,2,2,2],[2,3,3],[3,5]]
    

    示例 3:

    输入: candidates = [2], target = 1
    输出: []
    

    提示:

    • 1 <= candidates.length <= 30
    • 2 <= candidates[i] <= 40
    • candidates 的所有元素 互不相同
    • 1 <= target <= 40

2. 题目解析

- 题意分解

  1. 本题是计算多个集合之间的求和问题,每个集合由若干个同样的整数组成
  2. 同样整数和不能超过target,所以多个集合都是有限集合,因此每个集合能合成出来的数值也是有限的,可以用回溯法求解
  3. 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 可以在回溯算法中使用值传递

    2. 可以在回溯算法中使用引用传递,但是应用传递必须解决回退操作,可以使用堆栈结构

    3. 可以考虑存储过程值列表,最后将等于target的集合返回


- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见章节【最优算法】,代码文件包含在【相关资源】中

3. 代码展开

1) 标准求解【值传递+回溯】

使用列表作为值传递参数,逐层递归,完成回溯

页面功能测试,马马虎虎,超过40%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_base(self, candidates, target):def bracktracing(candidates, begin, ilen, path, ret, target):if target < 0:returnif target == 0:ret.append(path)returnfor iIdx in range(begin, ilen):bracktracing(candidates, iIdx, ilen, path + [candidates[iIdx]], ret, target - candidates[iIdx])ilen = len(candidates)path, result = [], []if ilen == 0:return resultbracktracing(candidates, 0, ilen, path, result, target)return resultaSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))# 运行结果
函数 combinationSum_base 的运行时间为 1076.25 ms;内存使用量为 12060.00 KB 执行结果 = 62271

2) 改进版一【引用传递+堆栈回溯】

使用列表作为引用传递参数,逐层递归,完成回溯

页面功能测试,马马虎虎,超越71%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_ext1(self, candidates, target):candidates.sort()path, result = [], []idx, isum = 0, 0def bracktracing(idx, isum, path):if sum(path) == target:result.append(path[:])returnfor jIdx in range(idx, len(candidates)):if isum + candidates[jIdx] > target:returnpath.append(candidates[jIdx])isum += candidates[jIdx]bracktracing(jIdx, isum, path)path.pop()isum -= candidates[jIdx]bracktracing(idx, isum, path)return resultaSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))# 运行结果
函数 combinationSum_base 的运行时间为 1076.25 ms;内存使用量为 12060.00 KB 执行结果 = 62271

3) 改进版二【过程值列表缓存+遍历后检索】

使用多维列表结构保存各数值对应的组合列表,遍历完成后下标检索对应组合列表

页面功能测试,马马虎虎,超过23%在这里插入图片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_ext2(self, candidates, target):import copycandidates.sort()dp = [[] for x in range(target + 1)]for candidate in candidates:for iIdx in range(candidate, target + 1):if candidate == iIdx:dp[iIdx].append([candidate])else:for combination in dp[iIdx - candidate]:tmpgroup = copy.deepcopy(combination)tmpgroup.append(candidate)dp[iIdx].append(tmpgroup)return dp[target]aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))# 运行结果
函数 combinationSum_base 的运行时间为 1076.25 ms;内存使用量为 12060.00 KB 执行结果 = 62271

4. 最优算法

根据本地日志分析,最优算法为第1种方式【值传递+回溯】combinationSum_base

本题测试数据,似乎能推出以下结论:

  1. 组合的回溯求解中,值传递性能优于引用传递的堆栈结构
  2. 内存对象过多后,性能下降明显,如combinationSum_ext2
nums = [x for x in range(10, 20)]
target = 200
aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.combinationSum_ext1, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.combinationSum_ext2, nums, target)
print(result['msg'], '执行结果 = {}'.format(len(result['result'])))# 算法本地速度实测比较
函数 combinationSum_base 的运行时间为 1076.25 ms;内存使用量为 12060.00 KB 执行结果 = 62271
函数 combinationSum_ext1 的运行时间为 1243.29 ms;内存使用量为 11848.00 KB 执行结果 = 62271
函数 combinationSum_ext2 的运行时间为 14627.27 ms;内存使用量为 16080.00 KB 执行结果 = 62271

5. 相关资源

本文代码已上传到CSDN,地址:Python算法题源代码_LeetCode(力扣)_组合总和

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/499160.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙OS应用编程实战:构建未来应用的基石

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 鸿蒙OS&#xff08;HarmonyOS&#xff0…

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…

docker save 命令 docker load 命令 快速复制容器

docker save 命令 docker load 命令 1、docker save 命令2、docker load 命令 1、docker save 命令 docker save 命令用于在系统上把正在使用的某个容器镜像 导出成容器镜像文件保存下载&#xff0c;以便在其他系统上导入这个容器镜像文件 以便快速在其他服务器上启动相同的容…

16. QML中的一些粒子特效

1.说明 在使用unity开发游戏时&#xff0c;都会涉及到一些特效的开发。实际上在QML中也提供了一些可以做特效的控件&#xff0c;称之为粒子系统。本篇博客主要记录一些使用粒子做特效的方式。 特效–火焰效果&#xff1a; 2. 案例汇总 2.1 案例1 效果展示&#xff1a; 粒子…

一文速览深度伪造检测(Detection of Deepfakes):未来技术的守门人

一文速览深度伪造检测&#xff08;Detection of Deepfakes&#xff09;&#xff1a;未来技术的守门人 前言一、Deepfakes技术原理卷积神经网络&#xff08;CNN&#xff09;&#xff1a;细致的艺术学徒生成对抗网络&#xff08;GAN&#xff09;&#xff1a;画家与评审的双重角色…

数仓模型设计方法论

在当今大数据时代&#xff0c;数据已经成为企业最重要的资产之一。而数据仓库作为企业数据管理和分析的核心基础设施&#xff0c;其设计方法论对于企业的数据治理和决策分析至关重要。本文将探索数仓模型设计的方法论&#xff0c;帮助读者更好地理解和应用数仓模型设计。 一、…

LeetCode 刷题 [C++] 第102题.二叉树的层序遍历

题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 题目分析 题目中要求层序遍历二叉树&#xff0c;即二叉树的广度优先搜索(BFS)。BFS一般使用队列的先入先出特性实现&#…

服了,阿里云服务器价格和腾讯云1元之差,如何选择?

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器62元一年&#xff0c;2核2G3M、2核4G、4核8G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配置价格表…

一图总结:华为销售体系(铁三角组织LTC流程)

《华为铁三角工作法》阅读了多遍&#xff0c;花了些时间整理了一张图对本书的框架性总结&#xff0c;从流程&#xff08;LTC&#xff09;、组织&#xff08;铁三角&#xff09;、激励和管理三个大方面概览华为销售体系。 核心是一靠流程&#xff0c;二靠团队&#xff0c;而前提…

RT-Thread studio上创建一个STM32F103的CAN通讯功能

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff08;2&#xff0…

【MySQL】MVCC机制

引入问题 首先看下面这张图&#xff0c;假如说一条数据经过了事务 2、3、4&#xff0c;到事务 5 的时候&#xff0c;进行两次查询&#xff0c;那这两次查询分别查询的是哪个事务版本的记录呢&#xff1f; 这就是我们要解决的问题&#xff0c;那么MVCC机制也就是为了解决这个问…

力扣hot100题解(python版29-32题)

29、删除链表的倒数第N个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&a…