力扣经典算法篇-44-组合总和(回溯问题)

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、解题

求所有组合的问题通常可以使用回溯算法就行求解。

回溯的基本实现步骤:
找到固定不变的量,每趟递归动态变化的量,结果集。
递归一定要有终止条件,终止条件要校验和添加结本趟结果到结果集合中。
循环递归,注意要先添加元素向前递归,之后进行回退操作;怎么添加的元素进行向后递归,就要怎么删除元素向前回溯。

方法一:(回溯法–结果校验处理)

利用回溯法的解答模版,可以获取所有可用排列的结果,但是可能造成重复问题。如:(2,2,3)和(2,3,2)实际上是想通过的结果。
所以保存结果时,需要校验是否重复,重复数据不能再次添加到结果集。

代码示例:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class Test50 {public static List<List<Integer>> combinationSum(int[] candidates, int target) {// 不变的结果集List<List<Integer>> result = new ArrayList<>();// 每趟变量可变的元素// 每趟添加的元素List<Integer> tempList = new ArrayList<>();// 添加元素的下标int index = 0;// 当前趟的结果和int sum = 0;// 递归(不变的:目标数组candidates,目标值target; 每趟变化的:临时数组tempList,添加元素下标index,每一趟当前和sum; 结果集)goAndBack(candidates, target, tempList, index, sum, result);return result;}private static void goAndBack(int[] candidates, int target, List<Integer> tempList, int index, int sum, List<List<Integer>> result) {if (sum >= target) {// 大于等于目标值时,可以结束当前趟遍历if (sum == target) {// 当前趟元素排序后校验结果集是否存在,不存在可以添加到结果集ArrayList<Integer> oneGoal = new ArrayList<>(tempList);Collections.sort(oneGoal);if (!result.contains(oneGoal)){result.add(oneGoal);}}// 结果本趟递归,向前回溯return;}for (int i = 0; i < candidates.length; i++) {    // 因为元素可以重复添加,所以这里每次都从0号位置开始添加// 添加元素,计算和,向后递归tempList.add(candidates[i]);sum = sum + candidates[i];goAndBack(candidates, target, tempList, index + 1, sum + candidates[i], result);// 删除添加的元素,减去当前值,向前回溯sum = sum - candidates[i];tempList.remove(index);   // 或tempList.remove(tempList.size()-1); }}public static void main(String[] args) {int[] candidates = {2, 3, 6, 7};int target = 7;System.out.println(combinationSum(candidates, target));}
}

方法二:(回溯法–指定遍历的起始位置)

上面的方法一中,每次都是从位置0开始遍历添加元素,直到符合条件为止,相对而言,递归和回溯的次数都比较多。
可以换一种方式,在向后递归的时候,指定起始遍历的位置,即:下一次对的起始位置也是本次递归的起始位置,不是从0开始。这样就在遍历组装结果的过程中避免了重复的可能,减少遍历和比较的次数,效率更高。

代码示例:

 public List<List<Integer>> combinationSum(int[] candidates, int target) {List<List<Integer>> ans = new ArrayList<>();List<Integer> temp = new ArrayList<>();dfs(ans, temp, 0, 0, candidates, target);return ans;}public void dfs(List<List<Integer>> ans, List<Integer> temp, int index, int sum, int[] candidates, int target) {if (sum >= target) {if (sum == target) {ans.add(new ArrayList<>(temp));}return;}for (int i = index; i < candidates.length; i++) {// 添加元素,向后递归temp.add(candidates[i]);dfs(ans, temp, i, sum + candidates[i], candidates, target);     // 下一次遍历的位置i,最小也是index,避免过度回溯// 删除元素,向前回溯temp.remove(temp.size() - 1);}}

向阳前行,Dare To Be!!!

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

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

相关文章

矩阵与高斯消元:数学算法在计算机领域的应用

一、概述和基本概念 矩阵&#xff0c;类似于在 C 中我们看到的二维数组。它有两个维度&#xff0c;行和列。下面是一个典型的矩阵&#xff1a; M[12342345445610111213] M \begin{bmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 4 & 4 & 5 &…

【补题】CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!) D. K-good

题意&#xff1a;给一个n&#xff0c;如果能被k个数整除&#xff0c;要求这k个数%k后不相同&#xff0c;问如果可以&#xff0c;任意k是多少&#xff0c;如果不可以输出-1 思路&#xff1a; D. K-good_牛客博客 从来没见过&#xff0c;太诡异了&#xff0c;做题做少了 1.…

LLM推理框架的“权力的游戏”:vLLM之后的群雄逐鹿

既然我们已经深入探讨了本地与云端的两大代表Ollama和vLLM&#xff0c;是时候将视野拓宽&#xff0c;检视一下在高性能推理这片“高手如云”的竞技场中&#xff0c;还有哪些重量级的玩家。vLLM的出现点燃了战火&#xff0c;但远非终点。 欢迎来到LLM推理框架的“后vLLM时代”—…

TDengine IDMP 背后的技术三问:目录、标准与情景

过去十年&#xff0c;#工业 和#物联网 场景经历了快速的#数字化 建设&#xff1a;传感器接入、系统联网、数据上云……数据平台已能轻松承载每秒千万级别的写入&#xff0c;每天几 TB 的存储量。但今天再回头看&#xff0c;这些看似“完成”的系统&#xff0c;实际上只解决了一…

MyBatis基础操作完整指南

文章目录MyBatis简介环境搭建Maven依赖数据库表结构核心配置MyBatis配置文件数据库配置文件实体类基础CRUD操作Mapper接口Mapper XML映射文件工具类测试类动态SQL常用标签高级特性一对一关联映射一对多关联映射分页查询使用注解方式MyBatis简介 MyBatis是Apache的一个开源项目…

go与grpc

目录下载与安装遇到的问题cmd中protoc找不到命令cmd中--go_out: protoc-gen-go: Plugin failed with status code 1.下载与安装 下载protoc&#xff1a; https://github.com/protocolbuffers/protobuf/releases 点击下载相应电脑版本即可&#xff0c;我是windows系统下载了pro…

2025年AI面试重构招聘新生态

当企业面临业务扩张与人才竞争的双重压力&#xff0c;传统招聘模式已难以满足高效、精准、公平的人才筛选需求。尤其在校招季、蓝领用工潮等关键节点&#xff0c;面试官超负荷运转、跨地域协调困难、评估标准模糊等问题频发。AI技术的深度介入正推动招聘行业从“经验驱动”向“…

Rust进阶-part5-trait

Rust进阶[part5]_trait trait概述 在 Rust 中,trait 是一种定义共享行为的方式。它类似于其他语言中的接口,允许我们定义一组方法签名,然后让不同的类型去实现这些方法。通过 trait,我们可以实现多态性,即不同类型可以以统一的方式处理。 普通实现 使用 trait 关键字来…

【人工智能-18】机器学习:决策树、随机森林

上一期【人工智能-17】机器学习&#xff1a;KNN算法、模型选择和调优、朴素贝叶斯分类 文章目录一、决策树1.使用理由2.技术二、随机森林1.使用理由2.原理核心&#xff1a;Bagging 随机特征子集3.优点和缺点一、决策树 决策树是一种监督学习算法&#xff0c;主要用于分类&…

RFID高频读写器在工业生产线的使用优势

在工业4.0浪潮下&#xff0c;智能制造对生产效率与精准度的要求日益提升。RFID技术凭借其独特的技术优势&#xff0c;成为工业场景中实现数据实时采集与流程优化的关键工具。本文主要从RFID高频读写器出发&#xff0c;系统解析其在工业生产线中的使用优势。RFID高频读写器一、技…

大模型学习笔记

prompt 提示词的构成&#xff1a; 指示&#xff1a;描述让它做什么上下文&#xff1a;给出与任务相关的背景信息输入&#xff1a; 任务的输入信息输出&#xff1a;输出的格式 生成与检索 生成&#xff1a; 优点&#xff1a;内容的多样性、创造性缺点&#xff1a;存在不可控制 检…

龙虎榜——20250806

上证指数继续收阳线&#xff0c;创新高的概率较大&#xff0c;个股上涨多于下跌&#xff0c;但板块轮动较明显&#xff0c;高位板块注意风险。深证指数较昨天放量收阳线&#xff0c;站上5日和10日均线继续上线&#xff0c;大科技方向资金关注更多。2025年8月6日龙虎榜行业方向分…

数据可视化发展历程

数据可视化是数据描述的图形表示&#xff0c;是当今数据分析发展最快速、最引人注目的领域之一。借助于可视化工具的发展&#xff0c;或朴实&#xff0c;或优雅&#xff0c;或绚烂的可视化作品给我们讲述着各种数据故事。在这个领域中&#xff0c;科学、技术和艺术完美地结合在…

深入理解C++中的stack、queue和priority_queue

目录 前言 1. stack&#xff08;栈&#xff09; 1.1 基本概念 1.2 常用接口 1.3 应用示例&#xff1a;最小栈 1.4 模拟实现 2. queue&#xff08;队列&#xff09; 2.1 基本概念 2.2 常用接口 2.3 模拟实现 3. priority_queue&#xff08;优先队列&#xff09; 3.1…

C++ 操作 Redis 客户端

引言 前面几篇文章都在介绍 Redis 原生命令行客户端&#xff0c;在实际应用开发中&#xff0c;开发人员更希望使用针对特定编程语言的专用客户端&#xff0c;通过编程的方式操作 Redis 数据库。因此&#xff0c;Redis 支持多种编程语言。本文将介绍 如何使用 C 语言来操作 Red…

批量提问程序开发方案:基于Python的百度文小言接口实现

批量提问程序开发方案&#xff1a;基于Python的百度文小言接口实现 1. 项目概述 1.1 项目背景 在现代信息检索和自动化办公场景中&#xff0c;批量提问功能已成为提高工作效率的重要工具。本项目旨在开发一个基于Python的批量提问程序&#xff0c;专门针对百度文小言平台&am…

Apollo中三种相机外参的可视化分析

Apollo中三种相机外参的可视化分析一、什么是相机外参&#xff1f;为什么需要可视化&#xff1f;二、不同外参来源对比三、详细操作步骤1. 环境准备2. 获取 NuScenes外参数据3. 外参到空间位置的转换及可视化四、可视化对比1. NuScenes数据集外参2. Apollo BEV模型外参3. Apoll…

虚拟化KVM常用命令汇总

KVM&#xff08;Kernel-based Virtual Machine&#xff09;是一种开源的硬件虚拟化解决方案&#xff0c;它是 Linux 内核的一部分&#xff0c;允许在支持虚拟化技术的硬件&#xff08;如 Intel VT-x 或 AMD-V&#xff09;上运行虚拟机。KVM 将 Linux 内核转变为一个裸机虚拟机监…

6s081环境配置以及使用vscode连接本地wsl2

6s081环境配置以及使用vscode连接wsl2 本人环境&#xff1a;windows11、wsl2ubuntu20.04 课程&#xff1a;6s081的2020版本的:https://pdos.csail.mit.edu/6.S081/2020/schedule.html 一、wsl2ubuntu20.04配置6s081环境 注&#xff1a;关于如何在window中安装wsl&#xff0c;这…

C++实现线程池(3)缓存线程池

三. CachedThreadPool 的实现3.1 需求:动态调整线程数量&#xff1a;与 FixedThreadPool 不同&#xff0c;CachedThreadPool 的线程数量是动态调整的。当有新任务提交时&#xff0c;如果线程池中有空闲的线程&#xff0c;则会立即使用空闲线程执行任务&#xff1b;如果线程池中…