字符串的全排列-递归算法

题目:给定字符串S[0...N-1],设计算法,枚举S的全排列。

假设字符串为“1234”,首先考虑1,然后问题就变成了考虑“234”的全排列,所以问题规模缩小了1,然后再考虑2,依次类推。可以采用递归算法。

1-234

2-134

3-124

4-123

假设有重复字符,则重复字符的全排列就是每个字符分别与它后面非重复出现的字符交换。

1 #include <iostream>
  2 #include <string>
  3
  4 using namespace std;
  5
  6 //递归算法
  7 void swap(char &c1, char &c2)
  8 {
  9     char temp = c1;
 10     c1 = c2;
 11     c2 = temp;
 12     return;
 13 }
 14 //判断是否交换
 15 bool IsSwap(string str,int from, int to)
 16 {
 17     //默认交换
 18     bool cnt = true;
 19     for(int i = from; i < to; ++i)
 20     {
 21         if(str[i] == str[to])
 22         {
 23             cnt = false;
 24             break;
 25         }
 26     }
 27     return cnt;
 28 }
 29 //from和to 是下标
 30 void Permutation(string str, int from, int to)
 31 {
 32     if(from == to)
 33     {
 34         for(int i = 0; i <= to; ++i)
 35         {
 36             cout << str[i];
 37         }
 38         cout << endl;
 39         return;
 40     }
 41     for(int i = from; i <= to; ++i)
 42     {
 43         if(!IsSwap(str,from, i))
 44             continue;
 45         swap(str[i], str[from]);
 46         Permutation(str, from + 1, to);
 47         swap(str[i], str[from]);
 48     }
 49     return;
 50 }
 51
 52 int main(int argc, const char *argv[])
 53 {
 54     string str = "1223";
 55     int len = str.size();
 56     Permutation(str, 0, len-1);
 57     return 0;
 58 }                                       

测试用例为“1234”和“1223”

结果为:

这里有个小技巧,可以减少有重复字符全排列的时间复杂度,通过空间换时间。

如果是单字符,可以使用mark[256]。

如果是整数,可以遍历整数得到最大值max和最小值min,使用mark[max-min+1]。

如果是浮点数或者其他结构数据,用Hash(事实上,如果发现整数间变化太大,也应该考虑使用Hash;并且,可以认为整数情况是最朴素的Hash)

将mark数组全部赋0,每次交换前将mark[i]赋1,然后每次要进行交换前进行判断即可。

代码只修改这一部分,其余部分一样:

 40  int mark[256];
 41     for(int i = 0; i < 256; ++i)
 42     {
 43         mark[i] = 0;
 44     }
 45     for(int i = from; i <= to; ++i)
 46     {
 47         if(mark[str[i]] == 1)
 48             continue;
 49         /*if(!IsSwap(str,from, i))
 50             continue;
 51         */
 52         mark[str[i]] = 1;
 53         swap(str[i], str[from]);
 54         Permutation(str, from + 1, to);
 55         swap(str[i], str[from]);
 56     }
 57     return;
 58 }
时间: 2024-07-29 07:42:31

字符串的全排列-递归算法的相关文章

字符串的全排列JAVA实现

package com.kpp; /** * 求字符串的全排列 * 递归的思想 * 比如 abcde 先求出abcd的全排列,然后将e分别插入全排列的5个位置 * a 全排列 a * ab 全排列 ab ba * abd 全排列即是 cab acb abc cba bca bac * * @author kpp * */ public class QuanPaiLie { /** * @param args */ public static void main(String[] args) {

28. 字符串的全排列之第2篇[string permutation with repeating chars]

[本文链接] http://www.cnblogs.com/hellogiser/p/string-permutation-with-repeating-chars.html [题目] 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则输出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba.例如输入字符串aba,则输出由字符a.b所能排列出来的所有字符串aab.aba.baa. [分析] 之前的博文28.字符串的排列之第1篇[String

字符串数组全排列——逐个追加组合算法

我们在笔试面试过程中经常会遇到关于排列与组合的问题,其实这些可以通过递归简单的实现,看下面两个例子: (1)关于字符串排列的问题 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则输出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 可以这样想:固定第一个字符a,求后面两个字符bc的排列.当两个字符bc的排列求好之后,我们把第一个字符a和后面的b交换,得到bac;接着我们固定第一个字符b,求后面两个字符ac的排列.现在是把c放到第一位

显示字符串的全排列

显示字符串的全排列: 1 public static void AllSequenceofString(String string){ 2 if(string == null) 3 return; 4 char[] chars = string.toCharArray(); 5 Permutation(chars,0); 6 } 7 private static void Permutation(char[] chars, int index) { 8 // TODO Auto-generate

含重复字符的字符串的全排列问题(Java)

本代码既可以输出重复和不重复字符串的全排列 /** * 含重复字符的字符串的全排列问题 * * */ public class S_28 { public static int count = 0; public static void main(String[] args){ char[] list = {'a','b','c'}; char[] list1 = {'a','b','b'}; //permutation(list); permutation(list1); System.out

字符串的全排列(java)

差不多半个月没写博客了,今天再写一篇. 字符串全排列相信大家都不陌生,对于我来说真的是写了又忘,忘了又写,所以决定写成一篇博客,废话不多说下面我来分析问题: 问题描述:给定一个字符串写出它的全排列,例如ab,全排列是ab,ba,而abc的全排列abc,acb,bac,bca,cab,cba. 解题思路:我们以具体例子分析,假如abc,如上所示,它的全排列是不是就是把字符串中每一个字符,放在第一位,然后再对剩下的字符串做全排列,如把a放在第一位,剩下bc 全排列是bc,cb,组合起来就是abc,a

《编程之法》1.3字符串的全排列,组合,重复排列,八皇后问题

题目描述:输入一个字符串,打印出该字符串中字符的所有排列,例如输入"abc",输出"abc","acb","bac","bca","cab","cba" 解法一:递归实现 类似于图的深度遍历搜索求全路径的算法,每次交换两个数,并输出,按照递归的方法,如求abcd的全排序,1:先求abcd后面的bcd全排列(同样先求b后面cd的全排列,然后b与后面的元素依次交换);2:

算法笔记_025:字符串的全排列(Java)

目录 1 问题描述 2 解决方案 2.1 递归实现 2.2 字典序排列实现   1 问题描述 输入一个字符串,打印出该字符串的所有排列.例如,输入字符串"abc",则输出有字符'a','b','c'所能排列出来的所有字符串"abc","acb","bac","bca","cab","cba". 2 解决方案 2.1 递归实现 从字符串中选出一个字符作为排列的第一个字符

js-FCC算法-No repeats please字符串的全排列

把一个字符串中的字符重新排列生成新的字符串,返回新生成的字符串里没有连续重复字符的字符串个数.连续重复只以单个字符为准 例如, aab 应该返回 2 因为它总共有6中排列 (aab, aab, aba, aba, baa, baa), 但是只有两个 (aba and aba)没有连续重复的字符 (在本例中是 a). 从网上资料获得了一些思路,我的代码: function permAlone(str) { var arr=str.split(""); var perarr=[]; var