回溯,所有回溯都可以转换成树形结构进行解决

我们将树形结构分为纵向和横向两个方面
递归是纵向循环,也就是纵向方面,到了叶子节点就收网回溯
循环是横向循环,也就是横向方面,到了数组末尾就结束
回溯属于是将二叉树的子节点状态回归到了其父节点时的状态,说白了,就好比循环,哪怕循环变量i被利用了无数次,只要i的值不发生变化,那么循环就始终不会更改它的目标

回溯模板
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

k其实就已经限制树的深度,因为就取k个元素,树再往下深了没有意义
注意树深的限制,该限制可以帮我们找到叶子节点从而得到结果
叶子节点就是要收集的结果集,其实这也不一定,没准题目要你把所有节点都搜集一遍

回溯问题的经典概述                                                                                                                        组合问题:N个数里面按一定规则找出k个数的集合
排列问题:N个数按一定规则全排列,有几种排列方式
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
棋盘问题:N皇后,解数独等等

for循环横向遍历,递归纵向遍历,回溯不断调整结果集
剪枝精髓是:for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够 题目要求的k个元素了,就没有必要搜索了。
所以我们要去重的是同一树层上的“使用过”,同一树枝上的都是一个组合里的元素,不用去重
同一树层是for循环,而同一树枝是递归

强调一下,树层去重的话,需要对数组排序,但树枝可能不会重复

树层是同一个父节点的不断追加,如果数层出现重复需要进行修改,则需要回到从父结点看起

打个比方

1,1,2

1                    1                 2

11     12          12              

112

第一个1:1指向11,12

第二个1:1指向12

如何判断该树层重复,就需要回到最根本的父节点,父节点的递归中,如果这个点和上一个点相同,并且上一个点并没有被访问过,那就说明这是一个重复树枝(该点与上一个点相同,重复:且上一个点没被访问过,独立树枝)

树枝就不大可能重复了

树枝是同一个前缀的不断追加

递归中调用的元素属于本层元素,不会被递归传递到下一层,这些本层元素一直在该层,直到递归中的归到来
从递的角度来看,层数一层层向下,这些本层元素好像并没有什么效果,一旦通过归回到了该层,这些本层元素会发挥它们应有的作用,维护着本层的秩序和规则
class Solution {
public:
    vector<vector<int>>res;
    vector<int>path;
    void dfs(vector<int>&nums,int startindex)
    {
        if(path.size()>1) res.push_back(path);
        if(startindex>nums.size())
        {
            return;
        }

        unordered_set<int>uset;
        for(int i=startindex;i<nums.size();i++)
        {
            if( (!path.empty()&&nums[i]<path.back())||uset.find(nums[i])!=uset.end())
            {
                //路径数组非空,后一个数一定会大于数组末尾元素数字,或者
                continue;
            }
            uset.insert(nums[i]);//本层元素,到了下一层就没用了

            path.push_back(nums[i]);
            dfs(nums,i+1);
            path.pop_back();
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        dfs(nums,0);
        return res;
    }
};

本文部分代码和资料来自代码随想录,感谢代码随想录,感谢程序员Carl

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

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

相关文章

阿里云获取DASHSCOPE_API_KEY教程,以及配置DASHSCOPE_API_KEY环境变量

要获取阿里云的 DASHSCOPE_API_KEY&#xff08;通义千问API密钥&#xff09;&#xff0c;需要在阿里云平台上完成开通服务和创建密钥的流程。以下是具体步骤&#xff1a; 1. 开通通义千问API服务 登录阿里云账号 访问 阿里云官网&#xff0c;使用账号密码或RAM用户登录。 进入…

《去哪儿网Redis高并发实战:从问题定位到架构升级》

去哪儿网Redis高并发实战&#xff1a;从问题定位到架构升级 在互联网行业竞争日益激烈的当下&#xff0c;高并发场景下的系统性能优化一直是技术团队面临的重要挑战。对于去哪儿网这类在线旅游平台来说&#xff0c;节假日期间的流量高峰更是对系统架构的严峻考验。本文将深入剖…

Zynq + FreeRTOS + YAFFS2 + SQLite3 集成指南

Zynq FreeRTOS YAFFS2 SQLite3 集成指南 一、系统架构设计 #mermaid-svg-qvuP6slyza89wsiT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qvuP6slyza89wsiT .error-icon{fill:#552222;}#mermaid-svg-qvuP6slyz…

设计模式精讲 Day 6:适配器模式(Adapter Pattern)

【设计模式精讲 Day 6】适配器模式&#xff08;Adapter Pattern&#xff09; 文章内容 在“设计模式精讲”系列的第6天&#xff0c;我们将深入讲解适配器模式&#xff08;Adapter Pattern&#xff09;。作为结构型设计模式之一&#xff0c;适配器模式的核心思想是将一个类的接…

系统稳定性治理

一、微服务内部异常 描述 微服务Pod自动重启表现&#xff1a;服务波动&#xff08;响应时间不稳定&#xff09;、监控指标异常&#xff08;Pod重启次数增加&#xff0c;CPU/内存波动&#xff09;、Kubernetes事件记录容器重启原因影响&#xff1a;服务中断、性能波动、资源消耗…

多智能体协同的力量:赋能AI安全报告系统的智能设计之道

“设想一个由‘数据采集者’、‘风险分析师’、‘报告撰写员’甚至‘合规监督员’组成的虚拟团队&#xff0c;它们如何携手打造一份深度洞察、精准预警的危化安全报告&#xff1f;这正是多智能体协作在AI安全领域的魅力所在。” 一、挑战升级&#xff1a;单一AI难以应对的复杂性…

ceph pg 卡在 active+clean+remapped 状态

场景 ceph 环境中有个 osd.0 做了 raid0 ,后来想剔除掉,执行了 ceph osd out 0 然后等了很长时间等 pg 数据迁移到别的 osd,但是最后有一个 pg 状态卡在了 active+clean+remapped 状态。如下: ceph pg ls-by-osd 0 PG OBJECTS DEGRADED MISPLACED UNFOUND BYTES …

systemd[1]: Failed to start LSB: Bring up/down networking

使用ssh连接虚拟机服务时&#xff0c;连接异常&#xff0c;虚拟机系统centos 7&#xff0c;于是登录虚拟机&#xff0c;查看服务ip&#xff0c;发现配置的静态ip未生效。因此重启网卡systemctl restart network&#xff0c;出现报错&#xff0c;使用systemctl status network查…

Go 语言使用 excelize 库操作 Excel 的方法

在笔者开发的项目中&#xff0c;有操作excel的需要&#xff0c;由于go操作excel比较方便且功能强大&#xff0c;于是选择使用go来操作excel。github.com/360EntSecGroup-Skylar/excelize库是一个功能强大且易于使用的库&#xff0c;它支持创建、读取和修改 Excel 文件&#xff…

Java基础(三):逻辑运算符详解

Java基础系列文章 Java基础(一)&#xff1a;发展史、技术体系与JDK环境配置详解 Java基础(二)&#xff1a;八种基本数据类型详解 Java基础(三)&#xff1a;逻辑运算符详解 目录 一、什么是逻辑运算符&#xff1f;二、基础逻辑运算符&#xff08;3种&#xff09;1、&&…

Bugku-CTF-web

最近刷了一下 Bugku-CTF-web 的61-70题&#xff08;平台目前只有67&#xff09;&#xff0c;好难好难&#xff0c;全都是知识的盲区。各种代码审计&#xff0c;各种反序列化&#xff0c;各种反弹shell&#xff0c;各种模版注入&#xff0c;各种字符串绕过&#xff0c;可以说是W…

GitLab 工具如何提升我的工作效率

在当今快节奏的软件开发和技术创作领域&#xff0c;作为一名博主&#xff0c;高效的工作流程和强大的协作工具至关重要。GitLab 作为一款集成了版本控制、项目管理、持续集成与持续部署&#xff08;CI/CD&#xff09;等功能于一体的平台&#xff0c;为我的工作带来了巨大的便利…

Unity Addressable使用之服务器远程加载

本地模拟服务器加载 1、创建一个Profiles&#xff0c;将Remote设为Editor Hosted 2、在Addressables Group窗口将Profile设为Local Test 3、将某个Asset Groups设为Remote加载 4、Build资源 5、打开本地模拟服务器 Addressables Hosting 窗口是 Addressable 提供的一个内置本…

Java基础八股文 - 面试者心理历程与标准答案

Java基础八股文 - 面试者心理历程与标准答案 前言&#xff1a;如何应对Java基础面试问题 面试Java基础时&#xff0c;很多候选人会因为紧张而忘记平时熟悉的知识点。本文将从面试者的心理历程出发&#xff0c;教你如何在面试中用自己的思路组织答案&#xff0c;然后给出标准回…

学习笔记088——Windows配置Tomcat自启

1、下载 下载Windows版本tomcat。本文下载的版本是&#xff1a; apache-tomcat-9.0.31-windows-x64.zip 点击下载 注意&#xff1a;要确保bin目录下有 service.bat 文件&#xff01; 2、配置服务 解压后&#xff0c;终端进入bin⽬录&#xff0c;安装服务&#xff1a;service…

SSL证书怎么配置到服务器上 ?

在网络安全备受关注的当下&#xff0c;SSL证书已成为网站安全的标配。但仅有SSL证书还不够&#xff0c;正确将其配置到服务器上&#xff0c;才能真正发挥保障数据传输安全、验证网站身份的作用。由于服务器类型多样&#xff0c;不同服务器的SSL证书配置方法存在差异&#xff0c…

AI与SEO关键词协同进化

内容概要 人工智能&#xff08;AI&#xff09;与搜索引擎优化&#xff08;SEO&#xff09;的结合&#xff0c;正深刻变革着关键词策略的制定与执行方式。本文旨在探讨AI技术如何驱动SEO关键词领域的智能化进化&#xff0c;核心在于利用AI强大的数据处理与模式识别能力&#xf…

01.线性代数是如何将复杂的数据结构转化为可计算的数学问题,这个过程是如何进行的

将复杂数据结构转化为可计算的数学问题是数据科学、机器学习和算法设计中的核心环节。这一过程需要结合数据特性、数学理论和计算框架,通过系统化的抽象和建模实现。以下是具体转化流程及关键技术解析: 一、数据结构分析:解构原始数据的本质特征 1. 识别数据类型与结构特性…

华为OD机考-网上商城优惠活动-模拟(JAVA 2025B卷)

import java.util.Scanner;public class Test3 {static int mjq;static int dzq;static int wmkq;static class Group {int price;// 打折后价格int num;// 优惠券使用熟练}public static void main(String[] args) {Scanner scanner new Scanner(System.in);String input sc…

JavaScript 数据处理 - 将字符串按指定位数截断并放入数组(基础实现、使用正则表达式实现、使用正则表达式简化实现)

将字符串按指定位数截断并放入数组 1、基础实现 /*** 将字符串按指定位数截断并放入数组* param {string} str - 要处理的字符串* param {number} n - 每段截断的位数* returns {Array} 截断后的字符串数组*/ function splitStringByLength(str, n) {const result [];for (l…