全排列大杂烩——回溯算法

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

前言

回溯,顾名思义就是回到之前的状态,常见的有时空回溯(祖安小伙艾克)以及今天要了解的回溯算法

回溯算法是一种通过探索所有可能的候选解来找出所有解的通用算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会放弃该解,回退到上一步,并尝试其他的可能性。

回溯算法可以看成是一种有组织的穷举方法,算是暴力算法的优化吧

有以下特点:

1.系统性:会按照某种顺序系统性的探索空间

2.跳跃性:当发现当前的路径并不能得到解时,立即立即回溯,返回上一路径

概念听的有点困了,还是来看看题吧家人们

迎面向我们走来的时无重复项数字全排列!

无重复项数字全排列

既然有无重复项的那肯定就存在有重复项的,这个我们先按下不表

没有重复项数字的全排列_牛客题霸_牛客网

题意是给一组数字,然后返回数字的所有排列

思路讲解

这里刚好适用回溯算法

其实这类使用回溯算法的还有一个模板,相似的题目可以直接套用

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

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

这里使用的是b站大佬代码随想录讲的模板,他讲算法很清晰透彻,如果真有人看我这篇文章的话,也可以去b站看看人家讲算法

那么回到题目,这道题无非就是递归找出所有可能嘛

由于题目要返回的是多组数字,所以首先需要定义一个二维数组来存放最终要返回的结果;

 vector<vector<int>> res;

当然,这个数组得是个全局数组,因为每次找到结果后就要存放进去

接着还需要一个一维数组来存放单组数据

vector<int> path;

最后,还需要一个布尔类型的数组,表示当前数字再这个路径下有没有被使用,而且要初始化为false

vector<bool> used (num.size(),false);

前置工作做完了,就到代码的核心部分了, 首先明确的是,回溯使用了递归来进行实现,那么递归就有终止条件,这里的终止条件就是——path数组存满时,这时就表示找到了一钟排列方式;

所以终止条件就是当path数组的长度等于了题目给定数组的长度时,就向最终数组里存放一组数据

然后到下面的循环环节,循环次数肯定得是总数组的大小

然后还得判断,当前数字是否被使用过,因为在第二层循环时,数组中的第一个数字已经被使用了,所以就要加上判断,防止第一个数字被重复使用;如果当前的数字被使用过了,则跳过这次循环,进入下一层;

当数字未被使用过时,就要向path数组里存放,然后used数组也要标记该数字被使用了,=

然后,再进行递归,找path数组中的下一个元素

接着在递归结束后还要进行回溯,path数组pop,然后used数组讲当前位置赋为false

差不多是这样吧

代码:

    vector<int> path;
    vector<vector<int>> res;
    void backtracking(vector<int>num,vector<bool>used)
    {
        //递归终止条件
        if(path.size()==num.size())
        {
            res.push_back(path);
            return;
        }
        //一步步遍历
        for(int i=0;i<num.size();i++)
        {
            //如果当前位置已经被使用过,直接跳过当前循环
            if(used[i]==true) continue;
            path.push_back(num[i]);
            used[i]=true;
            backtracking(num, used);
            //进行回溯
            used[i]=false;
            path.pop_back();
        }
    }
    vector<vector<int> > permute(vector<int>& num) 
    {
        vector<bool> used (num.size(),false);
        backtracking(num, used);
        return res;
    }

然后下面这道题时是上面的延申

有重复项的全排列

有重复项数字的全排列_牛客题霸_牛客网

思路讲解

其实和上一道题总体思路一样,甚至代码80%都一样,只是加了一点处理

首先,有重复项就说明如果不去重到时候就会有重复的排列,所以一定要去重

那该怎么去重呢

我们假设排序后的数组为 [a, a, b],去重逻辑的工作方式:

  1. 第一个a被使用,标记为已使用

  2. 遇到第二个a时:

    • 如果前一个a未被使用(即回溯后被撤销的状态),说明我们正在尝试以不同的顺序使用相同元素

    • 这时跳过当前a,避免生成重复排列

所以只需要在循环判断时加上去重逻辑就行,当然为了方便去重,可以用sort函数先进行排序

vector<int> path;
    vector<vector<int>> res;
    void backtracking(vector<int>num,vector<bool>used)
    {
        if(path.size()==num.size())
        {
            res.push_back(path);
            return;
        }
        for(int i=0;i<num.size();i++)
        {
            //如果上一个元素和当前元素一样,且未被标记使用,则需要进行去重
            if(i>0&&used[i-1]==false&&num[i]==num[i-1]) continue;
            if(used[i]==true) continue;
            path.push_back(num[i]);
            used[i]=true;
            backtracking(num, used);
            path.pop_back();
            used[i]=false;
        }
    }
    vector<vector<int> > permuteUnique(vector<int>& num) 
    {
        sort(num.begin(), num.end());
        vector<bool> used(num.size(),false);
        backtracking(num, used);
        return res;
    }

下面这道题基本类似,刚好都讲了

字符串的排列

字符串的排列_牛客题霸_牛客网

题目大意和数字一样,只是换成了字符串

思路讲解

思路无二,但是也需要做些修改,首先path不能是数组了,因为返回值是string类型的数组,所以res才是数组,path只能当个string

除了会有重复元素所以需要去重和排序外,似乎没有什么区别

 vector<string> res;
    string path;
    void backtracking(string& str, vector<bool>used) {
        if (path.size() == str.size()) {
            res.push_back(path);
            return;
        }
        for (int i = 0; i < str.size(); i++) {
            if (used[i] == true) continue;
            if(str[i]==str[i-1]&&used[i-1]) continue;
            used[i] = true;
            path.push_back(str[i]);
            backtracking(str, used);
            used[i] = false;
            path.pop_back();
        }
    }
    vector<string> Permutation(string str) {
        sort(str.begin(),str.end());
        vector<bool> used(str.size(), false);
        backtracking(str, used);
        return res;
    }

西工大计算机考研上机考试真题复盘与备考心法 在计算机考研复试环节,上机考试是对考生编程实践能力的直接检验,其本质是要求将数据结构与算法理论知识转化为可运行的代码。这种考察方式不仅验证基础功底,更通过在线评测系统模拟真实工程场景,帮助导师筛选出具备解决实际问题能力的学生。对于备考者而言,围绕OJ平台进行系统刷题、熟悉输入输出格式与边界条件处理,是提升通过率的有效路径。全文聚焦西工大计算机考研上机考试,复盘真题规律与高频考点,解析字符串处理、模拟题、BFS等典型题型的解题策略,并提供从环境搭建到考场时间分配的完整备考方案,为冲刺985院校的考生提供可复用 阅读详情

相关推荐

02-基于ART-PI开发板创建USB CDC 虚拟串口设备

本例在ART-PI开发板上,基于RT-Thread 5.0,5虚拟了一个USB32 CDC串口设备。

arm_fan的专栏 1886

算法设计 寻宝问题

算法设计 寻宝问题 1. 问题描述 对于某个m*n的字符串数组,相当于一个m行n列的平面形状的方格。里面S表示起点,W表示障碍,B表示可走(但是不一定可以通),X表示出口。对于起点S,有8个方向可以走,当然前提是在没有障碍的情况之下,其中可以分为单步走(on foot)和跳步走(by jump)两种情况,从起点S开始追寻最短的出口路径count2。 2. 具体要求 Input 输入的第一行是一个整数n (0<=n<=20),表示测试用例的数量。下面的行是n个测试用例的数据。每个测试用例的第一行

oowadanoko的博客 1913

5分钟搞定!用ZLMediaKit搭建GB28181视频监控系统(含避坑指南)

本文提供了一份基于ZLMediaKit搭建GB28181视频监控系统的实战指南。文章详细介绍了从环境准备、核心组件(ZLMediaKit与SIP服务器)部署、摄像头配置到内外网穿透的完整流程,并重点分享了设备ID配置、防火墙设置等关键避坑经验,帮助开发者快速构建稳定可控的监控平台。

apple5的专栏 1084

​力扣解法汇总1417-重新格式化字符串

​力扣解法汇总1417-重新格式化字符串

分享+记录 405

3D slicer查看形变场

3Dslice显示数据和形变场 将需要可视化的数据也导入3Dslice,注意描述为volume(图1a),如果没有显示是因为路径中不能有中文,也就是moving图像。 (b) 图1、数据导入形变场和 将相应的形变场数据直接拖入3Dslice,并修改描述为形变场(图1b)。 点击transform菜单图2(a),然后勾选形变场可视化图2(b)。 (b) 图2...

fanre的专栏 1947

Zabbix安装与部署 系统环境:centos7.0

Zabbix安装与部署 系统环境:centos7.0

weixin_42485027的博客 2600

About 宝藏寻宝模拟(CSP真题)

CSP真题

GHX54188的博客 770

GEE:本地影像上传到GEE的Assets中,并输入机器学习算法中作为特征变量

当我们在 Google Earth Engine(GEE)中应用机器学习算法时,会输入一些影像作为特征变量数据,进一步根据这些特征影像去推理未知区域的数据。但是 GEE 平台上计算特征变量的 API 函数并不是非常全面,我们希望获得更多的特征用于分类。这个时候,我们可以将本地计算的特征影像上传到 GEE 中进行后续处理。本文记录了从本地上传特征数据到 GEE 的 Assets 中的教程,用于后续在 GEE 中分类或者回归使用。本文也可作为《》一文的补充。

养乐多的博客 1730

寻宝问题

琼斯博士在寻宝的过程中,来到了一个平面图呈矩形的封闭房间。 矩形的宽度为w,高度为h。为方便描述,我们将矩形左上角坐标定为(0, 0),右下角坐标定为(w, h)。 房间的入口在矩形上沿的中点(即(w/2, 0)),出口在矩形下沿的中点(即(w/2, h))。狡猾的魔王还放置了许多红外探测器,一旦进入探测器的探测半径以内,将触发警报。 现在琼斯博士向您求助,他能否全身而退不惊动魔王? 输入

Walk More Slowly 1535

【全网首发】2026华为OD双机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)

【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)

算法大师! 8784

【33】软考软件设计师——算法题(二):贪心法与回溯法深度精讲|第4题进阶满分攻略

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第33篇,承接第32篇分治法与动态规划,聚焦**下午第4题算法大题进阶核心**,详解贪心法与回溯法两大高频难点算法。全文超4000字深度拆解贪心法核心原理、贪心选择性质、局部最优推全局最优的底层逻辑,厘清贪心算法适用边界与经典误区;深挖回溯法深度优先遍历思想、递归回溯三步流程、可行性剪枝与最优性剪枝两大核心技巧;全覆盖活动选择、零钱兑换、01背包贪心禁区、八皇后、全排列等软考必考经典题型;配套标准化算法框架代码、考场填空模板、剪枝优化实操案例

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 439

[SDOI2015][BZOJ3991] 寻宝游戏|set|dfs序|虚树|树上倍增LCA

3991: [SDOI2015]寻宝游戏 Time Limit:40 SecMemory Limit:128 MBSubmit:427Solved:212[Submit][Status][Discuss] Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达。游戏开始时,玩家可以任意选...

weixin_30871905的博客 147

Triton server的部署、构建、backend插件机制代码梳理、模型加载、自定义C++backend流程

Triton inference server的部署、构建、backend机制代码详细梳理、模型加载过程、自定义C++backend流程.

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 473

所有博客导航

。。

nameofcsdn的博客 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

PTA练习-- 寻宝,小明有一张藏宝图,上面有m*n个房间,每个房间里面都有一个有一定价值的宝物,小明只能从左上角的房间进入收集宝物...(动态规划)

寻宝 小明有一张藏宝图,上面有m*n个房间,每个房间里面都有一个有一定价值的宝物,小明只能从左上角的房间进入收集宝物,且每次只能向右边或向下边的房间继续寻宝,最终只能从最右下的房间出来。请你帮小明计算下他最多可以收集到多少价值的宝物? 输入格式: 输入第一行给出两个正整数m,n(1=<m,n<=2000),随后给出m行数据,每行都包括n个正整数,中间用空格分割。 输出格式: 输出收集到的最大价值v,题目保证v<10^9。 输入样例: 4 4 1 18 9 3 7 10 6 12 5 13

Rightstar的博客 2806

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

51nod 算法马拉松 天堂里的游戏

还算是比较著名的博弈问题 天堂里的游戏 李陶冶 (命题人) System Message (测试) 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 多年后,每当Noder看到吉普赛人,就会想起那个遥远的下午。 Noder躺在草地上漫无目的的张望,二楼的咖啡馆在日光下闪着

bayaksha 848

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

problem set

1、调用malloc函数的时候好像一般都会在加上强制类型转换如(char *)malloc();不加强制类型转换有什么影响 Malloc向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

it小白专栏 690

POJ 1417 True Liars

题意:有两种人,一种人只会说真话,另一种人只会说假话。只会说真话的人有p1个,另一种人有p2个。给出m个指令,每个指令为a b yes/no,意思是,如果为yes,a说b是只说真话的人,如果为no,a说b是只说假话的人。注意,a可以为b。保证每个指令都是正确的,且相互之间不矛盾。问,能不能确定哪些人是说真话的人,如果能,输出所有只说真话的人;如果不能,输出no。 解法:首先,用并查集建树,每个节...

weixin_34306446的博客 158

【POJ】[1417]True Liars

并未完成

BoilTask Talk Show 739

[Bzoj3991]寻宝游戏(dfs序+set)

Description 题目链接 Solution 用set按dfs序维护当前的宝物序列,那么答案为相邻2个点的距离加上头尾2个的距离 Code #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <set> #define...

weixin_34161083的博客 185

【BZOJ3991】寻宝游戏(动态规划)

题面 BZOJ 题解 很明显,从任意一个有宝藏的点开始,每次走到相邻的dfsdfsdfs的节点就行了。 证明? 类似把一棵树上的关键点全部标记出来 显然是要走一个大环。 这样沿着dfsdfsdfs序从左至右依次便利是最优的。 用一个setsetset维护一下就行了 #include&lt;iostream&gt; #include&lt;cstdio&gt; #inclu...

小蒟蒻yyb的博客 645

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 216

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 314

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 589

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 750
上一篇: 缺失的第一个正整数——原地哈希
下一篇: 动态规划——做题五步法
宴之敖者、
博客等级 码龄4年 131粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值