总结帖:全排列Permutation,子集subset 递归模板

C语言全排列算法(最详细讲解) 对于全排列算法的详细讲解 阅读详情

两个经典递归模板,以前写过,现在再过一遍!


基本思路:

如果题目给的输入时数组,首先先要把数组转为ArrayList,因为ArrayList可以很方便地插入,删除,添加!

其次,递归函数的形式都一样,一共有3个参数,分别叫ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret 。 done存放已经处理过的数据,rest存放还没处理的数据,ret存放最后的结果。注意这里的Integer可以是泛型,任意的data type。


具体思路:

全排列:对A[0,1,2,3...n] 每次依次取一个元素,添加到done里,然后对剩下的rest递归,直到rest为空。所以总的结构就是一个for循环里面,有一个从rest取数据,递归,撤销的过程。所以总结一下就是,每次递归,轮流从rest里取数据,依次添加到done。

子集:每次取出rest的第一个元素,然后做决定是否添加到done里面,可以添加,也可以不添加,所以会有两个递归。所以总结一下就是,每次递归,总是取rest的第一个数据,然后做两种选择。


import java.util.*;

public class HelloWorld{

    public static void main(String []args){
        int[] A = {1,2,3};
        subset(A);
        permutation(A);
        
        
        String s = "abc";
        permutationStringRec(new StringBuilder(), new StringBuilder(s));
    }
     
    
    // ======================================================= permutation
    public static void permutation(int[] A) {
        ArrayList<Integer> rest = new ArrayList<Integer>();
        ArrayList<Integer> done = new ArrayList<Integer>();
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
        
        for(int i : A) {
            rest.add(i);
        }
        
        permutationRec(done, rest, ret);
        System.out.println(ret);
    }
    
    public static void permutationRec(ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret) {
        if(rest.size() == 0) {
            ret.add(new ArrayList<Integer>(done));
            return;
        }
        
        for(int i=0; i<rest.size(); i++) {
            int val = rest.get(i);      // 选择第i个元素,添加到done
            done.add(val);
            rest.remove(i);
            permutationRec(done, rest, ret);
            rest.add(i, val);
            done.remove(done.size()-1); 
        }
    }
    
    
    
    // ======================================================= subset
    public static void subset(int[] A) {
        ArrayList<Integer> rest = new ArrayList<Integer>();
        ArrayList<Integer> done = new ArrayList<Integer>();
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();
        
        for(int i : A) {
            rest.add(i);
        }
        
        subsetRec(done, rest, ret);
        System.out.println(ret);
    }
    
    public static void subsetRec(ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret) {
        if(rest.size() == 0) {
            ret.add(new ArrayList<Integer>(done));
            return;
        }
        
        int first = rest.remove(0);

        // 选择添加到done
        done.add(first);
        subsetRec(done, rest, ret);
        done.remove(done.size()-1);
        
        // 选择不添加到done
        subsetRec(done, rest, ret);
        
        
        rest.add(0, first);
    }
    
    
    
    
    
    // ======================================== permutationStringRec 另一种用StringBuilder的变型版
    public static void permutationStringRec(StringBuilder done, StringBuilder rest){
        if(rest.length() == 0) {
            System.out.println(done.toString());
            return;
        }
        
        for(int i=0; i<rest.length(); i++) {
            char c = rest.charAt(i);
            done.append(c);
            rest.deleteCharAt(i);
            permutationStringRec(done, rest);
            rest.insert(i, c);
            done.deleteCharAt(done.length()-1);
        }
    }
    
    
}




DFS全排列模板详解:回溯算法核心思想与工程实践 深度优先搜索(DFS)是计算机科学中最基础的遍历与搜索策略之一,其思想可应用于排列组合、路径规划、博弈树求解等众多场景。回溯算法作为DFS的经典实现,遵循“选择→递归→撤销”的循环,在状态空间中逐层试探并回退。全排列问题正是理解回溯的母题:通过递归深度表示决策层数,用标记数组记录已选元素,再以具体长度作为终止条件,即可穷举所有排列。过程中,撤销操作和剪枝条件决定结果正确性与效率,尤其处理重复元素时,排序后配合“同层去重”能显著减少无效分支。该模板可自然迁移至组合、子集、N皇后等问题。本文逐行拆解全排列的标记 阅读详情

相关推荐

Java【全排列 算法 模板】

全排列模板-数组 2013年 第四届 蓝桥杯【带分数】 全排列模板-字符数组 2014年 第五届 蓝桥杯【扑克排序】 全排列模板-无重复元素 2016年 第七届 蓝桥杯【凑算式】

upward 1945

子集与子集和问题(Subset sum)的递归回溯解

 所谓子集,是一个数学中的概念。例如一个集合S = {1,2,3,4,5},那么X = {1,3,5}就是它的一个子集,1+3+5等于9就是对应于X的一个子集和。其实子集对于一个数组来说,就是相当于一个子序列(不是子数组,因为子序列意味着可以不连续,而子数组往往是连续的);那么子集和也就是子序列和。另外,子集问题需要与数学中的“排列”问题区分开来。因为子集往往是无序的,

ruoshui222的专栏 3859

EndNote全文检索实战:如何快速配置学校图书馆资源并精准查找文献

本文详细介绍了EndNote全文检索功能的实战配置方法,核心在于通过正确设置OpenURL链接解析器,无缝对接学校图书馆资源,实现一键精准获取文献全文。文章提供了从理解机制、四步配置法到进阶技巧的完整指南,帮助科研人员高效管理海量PDF,构建个人知识体系,大幅提升文献调研与写作效率。

weixin_29228781的博客 278

全排列模板

全排列模板 1.介绍 全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。 通俗一点:比如给你一个整型数组,使用数组中的全部数字,组成的全部组合,并且和顺序有关。 比如:nums=[1,4,6] 它的全排类是:146,164,416,461,641,614。即3的阶乘中组合,即数学中的A(3,3)。 2.使用场景 一般使用暴力枚举所有情况,再检查这种情况是否满足条件,满足则记录下来,进一步操作。 3.代码实

苏瞳的博客 3089

Windows下用Python调用科大讯飞语音唤醒SDK的避坑指南(附完整代码)

本文详细介绍了在Windows平台使用Python调用科大讯飞语音唤醒SDK的全流程,包括环境配置、核心代码实现、典型问题解决方案及进阶开发技巧。通过完整的代码示例和避坑指南,帮助开发者快速集成语音唤醒功能,提升开发效率。

u0v1w2x3的博客 405

NX二次开发编译时dll自动数字签名及拷贝

在UG5.0开始,所有基于UG二次开发的DLL都要“签名”后才能被客户端上正版的NX调用。

菜鸟爱飞不飞的博客 2683

算法基础6 —— DFS(全排列 + 数独游戏 + 子集 + 马走日 + N皇后 + 迷宫)

DFS的算法 —— 不撞南墙不回头,不到黄河心不死 例1 全排列问题 例2 子集 例3 数独 例4 马走日 例5 N皇后 例6 迷宫 例7 染色 DFS总结与模板

smallrain6的博客 907

matlab内读取文件目录时斜杠和反斜杠的使用

@matlab内读取文件目录时斜杠和反斜杠的使用TOC matlab内读取文件目录时,斜杠和反斜杠的使用 最近被斜杠和反斜杠弄晕了,于是总结了一下,在此和大家分享一下。 代码 clear; clc; close all; I1= imread('..\zs1.jpg'); %和代码文件夹同目录的图片 (纯反斜杠) I2= imread('../zs2/zs2.j...

weixin_44456694的博客 6571

Java的全排列模板

c++有全排列函数,我们Java没有,所以我们只能自己手写了。模板二:使用hashset来帮助我们去重。

m0_73862548的博客 242

FT2004(D2000)开发实战之网口stmmac报错调试(Failed to reset the dma)

网口stmmac报错调试(Failed to reset the dma)

嵌入式Linux 3584

【QGIS入门实战精品教程】1.2:QGIS与ArcGIS的区别和联系

以下是GISGeography官方给出的两者之间的27点比较(译): 官方网址:https://gisgeography.com/qgis-arcgis-differences/ 1.QGIS容纳更多的数据格式 ArcGIS没有支持所有的数据格式,毫无疑问,QGIS在处理各种类型的数据时非常顺手,QGIS在数据格式方面是个多面手,在使用数据方面是它的长处。 QGIS使用GDAL/OGR库来读取和写入地理信息数据格式,支持超过70种矢量格式。QGIS一开始就是为了与PostGIS协作而诞生的,而支持的名单.

智慧空间实验室 2039

回溯算法核心:排列树与子集树模型详解与实战优化

回溯算法是深度优先搜索(DFS)在解空间上的系统化应用,其核心思想是通过递归尝试所有可能的解,并在不满足条件时回退。该技术为解决组合优化和排列问题提供了通用框架,尤其在处理解空间呈指数或阶乘级增长时,展现出强大的问题建模能力。其技术价值在于将复杂的暴力搜索过程结构化,通过清晰的决策路径(选/不选、定序)实现高效遍历。在实际工程中,回溯算法广泛应用于解决全排列、组合选择、N皇后、0-1背包等经典问题。本文聚焦于回溯算法的两种核心抽象模型——排列树与子集树,深入解析其标准模板、剪枝优化和常见避坑指南,帮助开发者

weixin_30376509的博客 299

【python爬虫--爬取电商商品及对其销量、好差评等数据进行分析】Python爬虫爬取电商商品及大数据分析-实战

选择目标电商网站:这里选择爬取两个不同电商网站(比如京东、淘宝)上的商品数据,包括商品名称、价格、销量和评价信息。编写爬虫:通过爬虫获取商品信息并保存数据。数据清洗与对齐:将两个电商网站抓取到的数据进行统一清洗和对齐。数据分析:进行销量分析、好评与差评分析等。

Dreams°的博客 4011

全排列、子集、组合、子序列

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 子集是指给定一组元素,从中选取0个或多个元素组成的集合。对于n个元素的集合,它将包含2^n个不同的子集,包括空集和全集。 全排列(Permutation):全排列是指给定一组元素,通过交换元素的位置,得到这组元素所有可能的排列方式。假设有n个元素,全排列将产生n!(n的阶乘)种不

qq_1763467007的博客 2312

告别传统RAG的痛点!Agent Skills让知识库检索更智能(本地知识库搭建新思路:用Agent Skills实现渐进式检索)

传统RAG在知识库检索中存在文档结构丢失、Token消耗大等问题 📚 Agent Skills通过分层索引、渐进式检索等设计,实现了更智能的本地知识库检索方案 🤖 本文详细介绍了Agent Skills的核心设计理念、与传统RAG的对比以及实践建议,帮助你搭建高效的知识库系统 ✅

XiaoqiangClub的博客 692

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java写递归

对递归进行基本的讲解,用java语言实现

随记 4178

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

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

Java 递归模板

在该递归函数中,我们首先创建一个Map,用于将父节点ID映射到其子节点。然后,我们传递给buildTree方法一个Map和一个父ID,它将返回一个节点列表,该列表包含具有父ID的所有子节点。如果一个节点没有子节点,则其子节点列表为空。

weixin_51510841的博客 149

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

lwip-2.0.3

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

windows中的subst与虚拟驱动器(盘符)

目录subset示例 subset 将路径与驱动器号关联。也就是把一个目录当作一个磁盘驱动器。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;语法如下: SUBST [drive1: [drive2:]path] SUBST drive1: /D 参数 描述 drive1: 指定要分配路径的虚拟驱动器。 [drive2:]path 指...

wuj的专栏 8894

全排列模板及历年蓝桥考题

全排列模板类型 1.数组-全排列模板: private static void f(int []arr,int k) { if(k==arr.length) { return; } for(int i=k;i<arr.length;i++) { swap(arr, i, k); f(arr, k+1); swap(arr, i, k+1); ...

Jing_Hua 488

回溯算法 一个公式就够了

目录 两个万能模板 1.子集 2.子集 II 3.组合 4.组合总和 5.组合总和 II 6.全排列 7.全排列 II 8.字符串的全排列 9.字母大小写全排列 两个万能模板 方法一相对顺序不变 从左往右走 start 控制层数 vector<vector<int>> vv; vector<int> v; dfs(vector<int>& nums, int start) { if(start == nums.s.

weixin_57882237的博客 865

[dfs模板]全排列

一个整数n(1<=n<=9)

no_play_no_games的博客 301

递归求集合子集

那个紫书上求子集只是1~n,并不是指定集合a的子集,其实很简单,一个BFS递归一下,用vector保存这个集合,有两个状态:1.取a[i]放vector中;2.不取a[i] 直接上代码: #include&lt;cstdio&gt; #include&lt;vector&gt; #include&lt;algorithm&gt; using namespace std; int a[100...

karry_zzj的博客 1585
上一篇: 话说NOIP一些会考到的算法
下一篇: 烙印的妙计
chiiis
博客等级 码龄14年 422粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值