首页 > 编程语言 >排列算法问题

排列算法问题

时间:2023-05-30 22:05:03浏览次数:43  
标签:arr 排列 ans 算法 问题 depth result permutation path

| 类循环排列

# tree DFS
def loop_permutation(arr, depth, path, result):
    if depth == len(arr):
        result.append(list(path))
        return
    for n in arr:
        path.append(n)
        loop_permutation(arr, depth + 1, path, result)
        path.pop()

ans = []
arr = [1,2]
loop_permutation(arr, depth=0, path=[], result=ans)
print(ans)

结果:

[[1, 1], [1, 2], [2, 1], [2, 2]]

| 全排列

对输入的 n 个数作全排列。 输入样例
3
1 2 3

输出样例

123
132
213
231
312
321

下面解法不是最优,见后交换。

# tree DFS
def full_permutation(arr, used, depth, path, result):
    if depth == len(arr):
        result.append(list(path))
        return
    for i,n in enumerate(arr):
        if used[i]: continue
        path.append(n)
        used[i] = 1
        full_permutation(arr, used, depth + 1, path, result)
        used[i] = 0
        path.pop()

ans = []
arr = [1,2,3]
used = [0]*len(arr)
full_permutation(arr, used, depth=0, path=[], result=ans)
print(ans)

 

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

1 、2 、3三个元素的全排列为:

{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}。

 

全排列的生成算法方法是将给定的序列中所有可能的全排列无重复无遗漏地枚举出来。此处全排列的定义是:从n个元素中取出m个元素进行排列,当n=m时这个排列被称为全排列。

字典序、邻位对换法、循环左移法、循环右移法、递增进位制法、递减进位制法都是常见的全排列生成算法。

 


解法1(递归)
如下图:要对1、2、3、4进行排序,第一个位置上的元素有四种可能:1或2或3或4,假如已经确定了第一个元素为4,剩下的第二个位置上可以是1、2、3,很显然这具有递归结构,如果原始要排列的数组顺序为1、2、3、4,现在只要分别交换1、2,1、3,1、4然后对剩下的3个元素进行递归的排列。

 

看下面的图,观察就知道交换思路了。f([1,2,3])=1+f([2,3] U 2+f([3,4]) U 3+f([1,2]))!

排列算法问题_sed

代码:


public  void Permutation(char chs[],int start )
    {
        if(start==chs.length-1)
        {
            Arrays.toString(chs);
            //如果已经到了数组的最后一个元素,前面的元素已经排好,输出。
        }
        for(int i=start;i<=chs.length-1;i++)
        {
        //把第一个元素分别与后面的元素进行交换,递归的调用其子数组进行排序
                Swap(chs,i,start);
                Permutation(chs,start+1);
                Swap(chs,i,start);
        //子数组排序返回后要将第一个元素交换回来。  
        //如果不交换回来会出错,比如说第一次1、2交换,第一个位置为2,子数组排序返回后如果不将1、2
        //交换回来第二次交换的时候就会将2、3交换,因此必须将1、2交换使1还是在第一个位置 
        }
    }
    public  void Swap(char chs[],int i,int j)
    {
        char temp;
        temp=chs[i];
        chs[i]=chs[j];
        chs[j]=temp;
    }

python实现:
def full_permutation(arr, depth, result):
    if depth == len(arr):
        result.append(list(arr))
        return
    for i in range(depth, len(arr)):
        arr[i], arr[depth] = arr[depth], arr[i]
        full_permutation(arr, depth + 1, result)
        arr[i], arr[depth] = arr[depth], arr[i]

ans = []
arr = [1,2,3]
full_permutation(arr, depth=0, result=ans)
print(ans)

结果:[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]

 

递归方法会对重复元素进行交换比如使用递归对{1,1}进行全排序会输出:{1,1},{1,1}两个重复的结果。要在排序的时候去掉重复结果,可以修改一下代码如下:

public static void Permutation(char chs[],int start)
    {
        if(start==end)
        {
            list.add(new String(chs));
        }
        for(int i=start;i<=chs.length-1;i++)
        {
            if(i==start||chs[i]!=chs[start])
            {
            //在排列的时候进行判断如果后面的元素与start相同时就不进行排序。
            //这样就可以避免对重复元素进行排序
                Swap(chs,i,start);
                Permutation(chs,start+1);
                Swap(chs,i,start);
            }
        }
    }

 

# tree DFS
def full_permutation(arr, depth, result):
    if depth == len(arr):
        result.append(list(arr))
        return
    for i in range(depth, len(arr)):
        if i == depth or arr[i] != arr[depth]:
            arr[i], arr[depth] = arr[depth], arr[i]
            full_permutation(arr, depth + 1, result)
            arr[i], arr[depth] = arr[depth], arr[i]

ans = []
arr = [1,1,3]
full_permutation(arr, depth=0, result=ans)
print(ans)

结果:[[1, 1, 3], [1, 3, 1], [3, 1, 1]]


 

标签:arr,排列,ans,算法,问题,depth,result,permutation,path
From: https://blog.51cto.com/u_11908275/6382280

相关文章

  • [NOIP2001 普及组] 装箱问题
    [NOIP2001普及组]装箱问题题目描述有一个箱子容量为\(V\),同时有\(n\)个物品,每个物品有一个体积。现在从\(n\)个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。输入格式第一行共一个整数\(V\),表示箱子容量。第二行共一个整数\(n\),表示......
  • 文心一言 VS 讯飞星火 VS chatgpt (26)-- 算法导论5.1 1题
    一、证明:假设在过程HIRE-ASSISTANT的第4行中,我们总能决定哪一个应聘者最佳。则意味着我们知道应聘者排名的全部次序。文心一言:证明:假设在过程HIRE-ASSISTANT的第4行中,我们总能决定哪一个应聘者最佳。则意味着我们知道应聘者排名的全部次序。在HIRE-ASSISTANT的第......
  • Pytorch多分类问题实战
    多分类问题实战定义一个简单的神经网络模型,并使用SGD优化算法进行训练和测试MNIST数据集importtorchimporttorch.nn.functionalasFimporttorch.optimasoptim"""torchvision可以帮助简化计算机视觉任务的实现,包括图像分类、目标检测、语义分割等。它提供了一些预训......
  • 背包问题(模板
    哼哼哼啊啊啊啊啊……顾冥思彝,就是背包出问题了……(bushi一个人在旅途中的人有一个最多能用M公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn.求此人能获得最大总价值。Input第1行:两个整数,M(背包容量,M<=200)和n(物品数量,n<=30);第2至n+1行:每行两个......
  • 解决右键没有vscode打开选项的问题 AHAI AHAI
    问题点击鼠标右键没有‘使用vscode打开’的选项。原因在安装时没有勾选相关选项解决办法先声明亲测有效。1.新建文本文件夹2.输入以下文本WindowsRegistryEditorVersion5.00[HKEY_CLASSES_ROOT\*\shell\VSCode]@="OpenwithCode""Icon"="D:\\Mic......
  • 【无人机三维路径规划】基于蚁群算法实现无人机三维路径规划含Matlab代码
    ⛄内容介绍随着无人机可执行任务的多样化,航迹规划成为其顺利完成任务的基本前提。针对该问题,提出了基于蚁群算法的无人机航迹规划方法。运用等效地形模拟方法,将作战区域中的敌方威胁、地形障碍等效为山峰,构建了无人机航迹规划的场景。以此为基础,采用抽象蚁群,对起始点和终点已知的......
  • 关于在 computed 使用 ref 获取 dom 结点为 undefined的问题
    原因:因为ref本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们,它们还不存在computed里面无法获取到ref解决方法:方法一:data:{isMount:false,},mounted(){this.isMount=true},computed:{if(this.isMount){console.l......
  • 算法刷题记录:[NOIP2017]图书管理员
    题目链接https://ac.nowcoder.com/acm/contest/19306/1050题目分析因为要求最小编号,并且该编号是以读者的编号结尾,这边直接排序+翻转,找开头的数。记录是因为看到某个大佬非常好的思路,直接对编号进行取模,就是末尾的数。如果想得到末尾的数,直接进行取模即可~~AC代码#include<......
  • 第五课 朴素贝叶斯算法
       朴素贝叶斯算法是机器学习中目前一个还在使用的算法,其依托于贝叶斯公式的概率计算,可用于NLP等分类任务。朴素贝叶斯算法的朴素,是因为其有2个较强或较主观的前提假设:样本间的特征(属性)是相互独立的样本特征(属性)取值服从高斯(正态)分布   由于自然界的数据分......
  • go exec.Command windows 参数引号转义问题
    Go在windows上调用本地进程传参时的一个天坑Golanggo在windows上exec.Command调用本地进程在传参的时候有一个天坑,举个栗子来说正常来说一般代码会这么写cmdLine:="notepad.exe"+`"D:\ProgramFiles\Notepad++\session.xml"`cmd:=exec.Command("cmd.exe","/c",cmdL......