博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排列组合【转】
阅读量:5964 次
发布时间:2019-06-19

本文共 2774 字,大约阅读时间需要 9 分钟。

(1) 全排列:

将数组看为一个集合,将集合分为两部分:0~s和s~e,其中0~s表示已经选出来的元素,而s~e表示还没有选择的元素。

perm(set, s, e)

{

顺序从s~e中选出一个元素与s交换(即选出一个元素)

调用perm(set, s + 1, e)

直到s>e,即剩余集合已经为空了,输出set

}

1 void perm(int list[], int s, int e, void (*cbk)(int list[]))  2 {      3     int i; 4     if(s > e)      5     { 6         (*cbk)(list); 7     } 8     else     9     {         10         for(i = s; i <= e; i++)11         {             12              swap(list, s, i);             13              perm(list, s + 1, e, cbk);             14              swap(list, s, i);         15         }16     }17 }

排列的非递归算法:

L算法作用于有序序列a_1 < a_2 < a_3 < ... < a_n 上(可以改写成≤的形式),其算法步骤如下:

  1. 输出序列本身
  2. 从右至左找到第一个a_j,使得a_j < a_{j+1}且a_{j+1} > a_{j+2} > ... > a_n
  3. 在a[j+1..n]中找到最小的a_k使得a_j < a_k,交换a_j和a_k
  4. 将a[j+1..n]逆序,输出当前序列
  5. 重复第2~5步,直到找不到第二步中合适的a_j

这种算法可以生成字典序的排列序列。

1 public static IEnumerable
FullPermutations
(IEnumerable
iter) where T : IComparable
2 { 3 var pool = iter.ToArray(); 4 while (true) 5 { 6 yield return pool.ToArray(); 7 int j = pool.Length - 2; 8 while (j >= 0 && pool[j].CompareTo(pool[j + 1]) >= 0) 9 {10 j--;11 }12 if (j < 0)13 yield break;14 int k = pool.Length - 1;15 while (k > j && pool[k].CompareTo(pool[j]) <= 0)16 {17 k--;18 }19 SwapItem(pool, j, k);20 Reverse(pool, j + 1, pool.Length - 1);21 }22 }23 private static void Reverse
(IList
lst, int s, int e)24 {25 while (s < e)26 {27 Swap(lst, s, e);28 s++;29 e--;30 }31 }

(2)组合

组合指从n个不同元素中取出m个元素来合成的一个组,这个组内元素没有顺序。使用C(n, k)表示从n个元素中取出k个元素的取法数。

每一次从集合中选出一个元素,然后对剩余的集合(n-1)进行一次k-1组合。反向地选取。

1 class Solution { 2 public: 3     vector
> combine(int n, int k) { 4 vector
r(k, 0); 5 recursive(n, k, r); 6 return ret; 7 } 8 9 void recursive(int n, int k, vector
&r) {10 if (k <= 0) {11 ret.push_back(r);12 return;13 }14 for (int i = n; i >= k; --i) {15 r[k - 1] = i;16 recursive(i - 1, k - 1, r);17 }18 }19 20 private:21 vector
> ret;22 };

 

 组合的非递归实现:

首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。     

然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为   
“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。     
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得   
到了最后一个组合。     
  例如求5中选3的组合:     
  1   1   1   0   0   //1,2,3     
  1   1   0   1   0   //1,2,4     
  1   0   1   1   0   //1,3,4     
  0   1   1   1   0   //2,3,4     
  1   1   0   0   1   //1,2,5     
  1   0   1   0   1   //1,3,5     
  0   1   1   0   1   //2,3,5     
  1   0   0   1   1   //1,4,5     
  0   1   0   1   1   //2,4,5     
  0   0   1   1   1   //3,4,5  

转载于:https://www.cnblogs.com/linyx/p/3651984.html

你可能感兴趣的文章
Excel 2013 表格自用技巧
查看>>
ubuntu安装VNC、Xfce桌面
查看>>
浅析支付系统的整体架构
查看>>
二位数组
查看>>
unix文件权限
查看>>
Python 模拟鼠键
查看>>
2017-2018-2 20155224『网络对抗技术』Exp7:网络欺诈防范
查看>>
tomcat 搭建
查看>>
Source Code Review
查看>>
分享一下我安装启动Jmeter出错时的解决办法
查看>>
java 调用process
查看>>
用a标签实现submit提交按钮的效果
查看>>
第十周
查看>>
毕向东_Java基础视频教程第20天_IO流(1~4)
查看>>
几图理解BeautifulSoup
查看>>
HashMap内部是如何实现的(转)
查看>>
交互设计[3]--点石成金
查看>>
java实现双向循环链表
查看>>
如何使用缓存提高程序性能
查看>>
【trie树】HDU4825 Xor Sum
查看>>