LeetCode题练习与总结:组合总和Ⅱ

一、题目

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

二、解题思路

  1. 排序:首先对 candidates 数组进行排序,这样可以避免在搜索过程中重复使用相同的元素,并且可以利用已经排序的特性来剪枝。

  2. 回溯搜索:使用递归函数进行回溯搜索,每次选择一个候选数字,并从剩余的候选数字中继续寻找可能的组合。

  3. 剪枝:在搜索过程中,如果当前的数字和已经达到或超过目标数 target,则直接返回,不再继续搜索。同时,如果当前选择的数字与上一次选择的数字相同,为了防止重复,也需要剪枝。

  4. 结果存储:当找到一个有效的组合时,将其添加到结果列表中。

三、具体代码

import java.util.ArrayList;
import java.util.List;public class Solution {public List<List<Integer>> combinationSum2(int[] candidates, int target) {List<List<Integer>> result = new ArrayList<>();List<Integer> combination = new ArrayList<>();Arrays.sort(candidates); // 对候选数组进行排序dfs(candidates, target, 0, combination, result);return result;}private void dfs(int[] candidates, int remain, int start, List<Integer> combination, List<List<Integer>> result) {if (remain == 0) { // 如果当前剩余值为0,说明找到了一个有效的组合result.add(new ArrayList<>(combination)); // 将当前组合添加到结果中return;}for (int i = start; i < candidates.length; i++) {if (remain - candidates[i] < 0) break; // 剪枝,如果当前数字使剩余值小于0,则不再继续if (i > start && candidates[i] == candidates[i - 1]) continue; // 跳过重复的数字combination.add(candidates[i]); // 选择当前数字dfs(candidates, remain - candidates[i], i + 1, combination, result); // 递归搜索剩余的组合combination.remove(combination.size() - 1); // 回溯,移除当前数字}}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 排序步骤Arrays.sort(candidates) 是对输入数组进行排序的步骤,其时间复杂度通常是 O(n log n),其中 n 是数组 candidates 的长度。

  • DFS搜索:深度优先搜索(DFS)是算法的核心部分。在每次递归中,我们遍历数组 candidates 并尝试每个可能的数字。由于数组已经排序,我们可以通过剪枝来避免不必要的搜索,例如跳过重复的数字和超出目标值的组合。理想情况下,每次递归都会减少目标值 remain,直到 remain 为 0,此时我们找到了一个有效的组合。在最坏的情况下,如果目标值 target 可以通过数组中的多个不同组合来达到,那么我们需要遍历所有可能的组合。因此,DFS搜索的时间复杂度可以表示为 O(2^n),其中 n 是数组 candidates 的长度。然而,由于剪枝的存在,实际的搜索空间会小得多。

  • 总结来说,排序步骤的时间复杂度是 O(n log n),而DFS搜索的时间复杂度在最坏情况下是 O(2^n),但实际执行时由于剪枝操作,时间复杂度会显著降低。

2. 空间复杂度
  • 递归栈:由于使用了递归,我们需要考虑递归栈的深度。在最坏的情况下,递归栈的深度可能达到 n,即数组 candidates 的长度,因为每次递归调用都可能创建一个新的递归层级。

  • 结果存储:结果列表 result 存储所有有效的组合。在最坏的情况下,如果每个候选数字都可以独立地构成目标值 target,那么结果列表的大小将接近 O(n),其中 n 是数组 candidates 的长度。

  • 综合考虑,总的空间复杂度可以表示为 O(n + result.size),其中 n 是数组 candidates 的长度,result.size 是结果列表的大小。在最坏的情况下,结果列表的大小可能会非常大,但是由于剪枝的存在,实际的 result.size 通常会小于 2^n

五、总结知识点

1. 数组排序:使用 Arrays.sort(candidates) 对候选人数组 candidates 进行排序。这是为了确保后续搜索过程中可以利用有序性来剪枝,避免重复使用相同的数字,并减少搜索空间。

2. 深度优先搜索(DFS):通过递归的方式遍历所有可能的组合。DFS 是一种用于遍历或搜索树或图的算法,它沿着一个分支深入到不能再深入为止,然后回溯到上一个分支点继续搜索,直到找到所需的解或遍历完所有的分支。

3. 回溯法:这是一种通过递归来实现的算法策略,它尝试分步解决问题。如果当前步骤不能得到有效的解,它将取消上一步或几步的计算,再通过其他可能的分步解决方案继续尝试。

4. 剪枝:在搜索过程中,通过一些条件判断来减少不必要的搜索,提高算法效率。在这段代码中,剪枝体现在两个地方:

  • 如果当前剩余值 remain 小于当前候选数字 candidates[i],则没有必要继续搜索,因为剩余值不可能通过更大的数字来满足。
  • 如果当前候选数字与前一个候选数字相同(即 candidates[i] == candidates[i - 1]),则跳过当前数字以避免重复的组合。

5. 动态规划思想:虽然代码中没有直接使用动态规划,但是其解决问题的思想与动态规划有相似之处。动态规划通常用于解决具有重叠子问题和最优子结构特性的问题,而这段代码通过递归和回溯来寻找问题的最优解。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

前端项目,个人笔记(二)【Vue-cli - 引入阿里矢量库图标 + 吸顶交互 + setup语法糖】

目录 1、项目中引入阿里矢量库图标 2、实现吸顶交互 3、语法糖--<script setup> 3.1、无需return 3.2、子组件接收父组件的值-props的使用 3.3、注册组件 1、项目中引入阿里矢量库图标 步骤一&#xff1a;进入阿里矢量库官网中&#xff1a;iconfont-阿里巴巴矢量…

教务管理系统(java+mysql+jdbc+Druid+三层架构)

1、项目要求 1.1数据库表描述 设计一个教务管理系统&#xff0c;要求如下&#xff1a; 系统涉及的表有 account表&#xff08;账号表&#xff09; teacher表&#xff08;教师表&#xff09; student表&#xff08;学生表&#xff09; course表 (课程表) score表&#xff08;成…

拦截器(springboot)

1、拦截器介绍 在SpringBoot中&#xff0c;拦截器是一种用于拦截请求并在处理请求之前或之后执行特定操作的机制。 拦截器可以用于实现一些通用的功能&#xff0c;例如身份验证、日志记录、性能监控等。 Springboot中的拦截器是通过实现HandlerInterceptor接口来实现的&#x…

[Halcon学习笔记]机器视觉缺陷检测常用方法对比总结

1、介绍 缺陷检测时机器视觉需求中最复杂难度较大的一类需求。究其原因&#xff0c;主要是在项目开发过程中首先要保证检测的稳定性和精度&#xff0c;又要实现缺陷检测的通用性&#xff0c;常见的缺陷&#xff1a;凹凸、污点瑕疵、划痕、裂缝、伤痕、毛刺等等类型种类繁杂&am…

uniapp 使用sqlite时无法读取到db文件中的数据

问题 {“code”:-1404,“message”:“android.database.sqlite.SQLiteException: no such table: user (Sqlite code 1): , while compiling: select * from user, (OS error - 2:No such file or directory),http://ask.dcloud.net.cn/article/282”} at pages/index/index.vu…

Python内置对象

Python是一种强大的、动态类型的高级编程语言&#xff0c;其内置对象是构成程序的基础元素。Python的内置对象包括数字、字符串、列表、元组、字典、集合、布尔值和None等&#xff0c;每种对象都有特定的类型和用途。 01 什么是内置对象 这些对象是编程语言的基础构建块&…

STP环路避免实验(思科)

华为设备参考&#xff1a;STP环路避免实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 Spanning Tree Protocol&#xff08;STP&#xff09;&#xff0c;即生成树协议&#xff0c;是一种数据链路层协议。主要作用是防止二层环路&#xff0c;并自适应网络变化和故障…

【AI案例】做AI视频如何实现数字人实时口型同步

首先,这个方案提供了一个令人瞩目的实时唇语同步API。这一技术能够将任何视频与任何语言的音频进行视觉配音,而且无需繁琐的训练过程。这样的功能极大地拓宽了视频内容的传播范围,使得无论语言背景如何,人们都能够理解并享受视频内容。 其次,这个API的适用性非常广泛,无…

Unity2D实现鼠标拖动物体移动(简单好抄)

1.新建脚本&#xff0c;并将脚本拖到你想要拖动的物体上即可 using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine;public class text : MonoBehaviour {private Vector3 offset;public int x 1;void OnMouseDown(…

第十三届“中关村青联杯”全国研究生数学建模竞赛-A题:多无人机协同任务规划(续)

目录 7.2 模型三的建立与求解 8 问题四:针对远程雷达的分步优化模型 9 问题五:模型分析

【Pandas】(2)DataFrame

Pandas 的 DataFrame 是一个二维的、大小可变的、异质型表格数据结构,带有标签化的轴(行和列)。简单来说,你可以将 DataFrame 看作是一个 Excel 表格或 SQL 数据表,在数据分析和数据处理中非常有用。 创建 DataFrame DataFrame 可以通过多种方式创建,最常用的是直接从字…

SAP前台处理:物料主数据创建<MM01>之销售视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

matlab软件基础

第1讲 MATLAB初步 MATLAB是矩阵实验室&#xff08;Matrix Laboratory&#xff09;的简称&#xff0c;是美国MathWorks公司出品的商业数学软件&#xff0c;用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境。MATLAB和Mathematica、Maple并称为三…

Linux 发布项目到OpenEuler虚拟机

后端&#xff1a;SpringBoot 前端&#xff1a;VUE3 操作系统&#xff1a;Linux 虚拟机&#xff1a;OpenEuler 发布项目是需要先关闭虚拟机上的防火墙 systemctl stop firewalld 一、运行后端项目到虚拟机 1、安装JDK软件包 查询Jdk是否已安装 dnf list installed | grep jd…

Redis数据结构对象中的类型检查与命令多态、内存回收

类型检查与命令多态 概述 redis中用于操作键的命令基本上可以分为两种类型。其中一种命令可以对任何类型的键执行&#xff0c;比如说DEL命令、EXPIRE命令、RENAME命令、TYPE命令、OBJECT命令等. 而另一种命令只能对特定类型的键执行&#xff0c;比如说 1.SET、GET、APPEND、…

OPTEE v3.20.0 FVP环境搭建

目录 一、前提条件 二、下载fvp代码 三、下载工具链 四、下载Foundation_Platform FVP平台 五、编译及运行 一、前提条件 1、安装如下的依赖工具 sudo apt-get install android-tools-adb android-tools-fastboot autoconf \ automake bc bison build-essential ccache c…

windows管理github代码

资料 windows SSH下载github

预处理 #pragma 命令详解

目录 1.引言 2.#pragma once 3.#pragma waring(...) 4.#pragma comment 4.1.lib 4.2.linker 5.#pragma region … /endregion … 6.#pragma optimize 7.#pragma message (message string) 8.#pragma omp parallel for 9.#pragma pack&#xff08;[ show ] |…

51单片机—AD/DA

目录 1.AD/DA元件介绍 2.运算放大器 3.原理分析 4.性能指标 5.内部芯片时序 6.程序实操 7.原理图 1.AD/DA元件介绍 一般传感器的值会随参数的值变化&#xff0c;AD一般对电压进行转换&#xff0c;AD有多个通道&#xff0c;但是DA只有一个通道&#xff0c;且AD的运用较为广…

路由器怎么做端口映射

路由器在网络中起到了连接不同设备和提供网络服务的重要作用。端口映射是一项常见的操作&#xff0c;它允许外部网络中的设备通过路由器访问内部网络中的设备。我们将介绍如何在路由器上进行端口映射的设置。 理解端口映射 在开始操作之前&#xff0c;我们需要了解一些基本概念…