排列组合(一)全排列

2024-05-16 13:48
文章标签 排列 排列组合

本文主要是介绍排列组合(一)全排列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述

输出一个字符数组元素的全排列

输入:'a','b','c'
结果:a,b,cb,a,cc,b,aa,c,bb,c,ac,a,b6

解决思路

这个问题是一个全排列问题,数学计算为A(n,n)。数学思路为,n个元素,第一位可以为n种可能,第二位可以有n-1种可能,以此类推所以全排列的种类一共有n!个。
以此为思路,我们可以从初始化顺序开始,

  1. 首先确定第一位,第一位一共有n种可能性,第一位分别和第1~n位进行交换,产生了n种排列方式,即这代表了第一位分别放置了n个不同元素;
  2. 放置第二位的元素,第一位放置完产生的n种可能顺序中,每种顺序的第二位只能有放置n-1种元素的可能性,第二位的元素只能在剩下的元素中选取,即从2~n位中选取一个元素作为第二位,用交换第2位到第n位产生第二位的n-1种放置方式;
  3. 放置第三位元素,和第二位类似,第三位元素的放置一共有n-2种可能性,在前两位放置完的基础上,每种放置顺序的第三位进行n-3种可能的放置。
  4. 依次类推,一直放置到最后一位,即到第n位,只有一种放置方式。这样就得到所有的排列。

代码实现

方式一:自己实现的非递归方式

    public static Queue<char[]> array2(char[] ch){// 新建一个队列Queue<char[]> queue = new LinkedList<>();// 将初始排列顺序入队queue.offer(ch);for(int i=0;i<ch.length;i++){// 辅助队列Queue<char[]> queue2 = new LinkedList<>();// 将队列中每种顺序分别出队进行下一位置所有可能的排列while(!queue.isEmpty()){// 将队列中的每种顺序出队char[] poll = queue.poll();// 当前位置一共有n-i种放置可能for(int j=i;j<ch.length;j++){// 对当前位置i进行n-i种可能放置,并将结果序列存储在辅助队列中queue2.offer(swap2(poll, i, j));}}// 将辅助队列中的结果存入原队列中queue = queue2;}return queue;}// 返回对输入的ch产生交换m与n位置后的新序列public static char[] swap2(char[] ch,int m,int n){// 新建新顺序数组char[] c = new char[ch.length];// 进行数组拷贝for(int i=0;i<ch.length;i++){c[i] = ch[i];}// 新数组交换位置c[m] = ch[n];c[n] = ch[m];return c;}

方式二:参考网上的代码递归实现

    // 记录个数static int count=0;// 交换ch中m和n位置public static void swap(char[] ch ,int m,int n){char t = ch[m];ch[m] = ch[n];ch[n] = t;}// 递归函数,ch为当前序列,current为当前位置public static void array(char[] ch,int current){// 当前位置为序列的最后一位时,输出该顺序if(current == ch.length-1){count++;System.out.println(Arrays.toString(ch));}else{// 关键代码for(int i=current;i<ch.length;i++){swap(ch, current, i);array(ch, current+1);swap(ch, current, i);}}}

递归方式关键在else中的部分,稍微有点难理解,但仔细看其实原理和上边一样

这篇关于排列组合(一)全排列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995087

相关文章

PHP字符串全排列

方法一: $str = 'abc';$a =str_split($str);perm($a, 0, count($a)-1);function perm(&$ar, $k, $m) {if($k == $m){ echo join('',$ar), PHP_EOL;}else {for($i=$k; $i<=$m; $i++) {swap($ar[$k], $ar[$i]);perm($ar

回溯——9.全排列

力扣题目链接 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解题思路 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II 1.题目 1.1递增子序列 题目链接:491. 非递减子序列 - 力扣(LeetCode) 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0491.%E9%80%92%E

python 实现第k个字典排列算法

第k个字典排列算法介绍 "第k个字典排列"算法通常指的是在给定的字符集合(例如,字符串中的字符)中,找到所有可能排列的第k个排列。这个问题可以通过多种方法解决,但一个常见且高效的方法是使用“下一个排列”算法的变种,或称为“第k个排列”的直接算法。 方法一:使用“下一个排列”的变种 生成所有排列:首先生成所有排列,但显然这种方法对于较大的输入集合是不切实际的,因为它涉及到大量的计算和存储。 排序

CSP-J选择题 - 排列组合

排列问题:有5名学生参加比赛,要求排成一排拍照,有多少种不同的排列方式?组合问题:从10本书中选出3本书送给朋友,有多少种不同的选择方式?排列问题:一个教室有7个座位,5个学生需要坐下,有多少种不同的排列方式?组合问题:从12个人中选出4个人组成一个团队,有多少种不同的方式?排列问题:一个密码由4个字母组成,字母可以重复使用,有多少种不同的排列组合?组合问题:从8个不同颜色的球中选出3个,不考虑顺

HLJUOJ1127 HDU2049(错排公式+排列组合)

1127: 递推求解专题练习二 Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 20   Solved: 8 [ Submit][ Status][ Web Board] Description 在电影院看电影时,总会有观众坐错座位号的情况。现在正在首播的青春爱情喜剧悬疑科幻大片《来治猩猩的你》观影现场爆满(满席)。 那么问题来了

C++解决:求排列数

描述 输入两个整数m,n,求m个数字中选n个数的排列数。(1<=n<=m<=50) 输入描述 两个正整数m和n。 输出描述 一个正整数表示排列数。 用例输入 1  6 5 用例输出 1  720 AC code #include<bits/stdc++.h>using namespace std;int fun(int n) {int sum=1;for(int i=n

每日一题~cf 970 div3 (A思维,B小模拟,C二分,D排列数建图成环,E 26个字母暴力+前缀和,F 逆元,G 数论gcd )

A 题意: 有 a 个1 ,b 个2.问是否能将这些数划分为两个数值相等的集合。 输出 YES 或者 NO —————— 问题等价于 将数组 分成两个数值相同的数组。所以sum 应该是偶数。也就是说 1 的个数是偶数。在i1的个数是偶数的情况下,将 2 分成两份,如果2 的个数是偶数,OK。如果是奇数那么需要1来补齐,如果1 的个数大于等于2那么可以补齐。(1 的个数是偶数,需要2个1来补齐,剩下

Java 排列组合字符串

例如 输入“abc”,打印所有可能出现的组合情况,并且消除重复值。 所谓排列组合如下: 排列组合,字符串:abcbcaacbabccbabaccab排列组合个数:6 实现代码(结合Java8 lambda表达式实现) import org.junit.Test;import java.util.ArrayList;import java.util.HashSet;impo

Leetcode刷题笔记:全排列

这是一个经典的回溯问题,下面是一个C++版本的解法: class Solution {public:void backtrack(vector<vector<int>>& res, vector<int>& nums, int start) {// 如果start到达nums的末尾,说明已经生成一个完整的排列if (start == nums.size()) {res.push_back(