算法 | 一文玩转全排列(附 实际案例分析)

本文深入讲解全排列的概念,包括无重复元素与有重复元素数组的递归实现,并通过实例分析,如带分数表示法问题,巩固全排列算法的理解。

一、全排列初识

从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n 个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。

二、问题引入

看了上面的定义还是一脸糊涂?不要紧,先看看下面的例子,你就会对全排列概念有个具体的认识:

对于一个给定的序列 a = [a1, a2, a3, … , an],请设计一个算法,用于输出这个序列的全部排列方式。
例如:a = [1, 2, 3]
输出
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]

这就是一个简单的全排列问题,单纯看上面的例子,貌似看起来很简单,用眼盯着可能都能算对,但是如果数组a的值个数增加到十个百个呢,那手算出来的概率就变得很低很低了,这时候就要利用算法来解决这一类问题。

三、递归实现

我们先考虑两种情况,

1. 数组元素互不相同

如果数组a中所有元素都不相同,每个数值都是唯一的,这时候问题就简单了,只需要进行dfs算法深度优先搜索,就可以实现,看代码:

import java.util.Arrays;

public class 全排列 {
   
   
	public static void main(String[] args) {
   
   
        int[] a = {
   
   1, 2, 3};//无重复元素
        allrange(a, 0, a.length - 1);

    }

    //全排列(递归回溯)
    private static void allrange(int[] a, int cursor, int end) {
   
   
        // 递归终止条件
        // 已经到序列结尾了 
        if (cursor == end) {
   
   
            System.out.println(Arrays.toString(a));
        }
        
        //初始 i=游标,因为 游标 之前的顺序已经确定了,不需要再排列了
        for (int i = cursor; i <= end; i++) {
   
   
        	
            swap(a, cursor, i);//固定游标,让 i 值不断变化,去输出当前后面的各种顺序的排列
            allrange(a, cursor + 1, end);     
            swap(a, cursor, i);// 回到交换之前的序列,这里可以理解为回溯,保证下一个值不受上一个值的影响(记忆抹去)
        }
    }

    private static void swap(int[] a, int cursor, int i) {
   
   
        int temp = a[cursor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值