剑指Offer - 九度1369 - 字符串的排列
2014-02-05 21:12
题目描述:

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入:

每个测试案例包括1行。

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

输出:

对应每组数据,按字典序输出所有排列。

样例输入:
abc
BCA
样例输出:
abc
acb
bac
bca
cab
cba
ABC
ACB
BAC
BCA
CAB
CBA
题意分析:
  给定一个字符串,输出有其中的字母所能构成的全部排列。
  首先,STL的algorithm中提供了next_permutation函数来输出下一个排列,所以你可以偷懒用用,当然也可以自己写一个。
  于是乎,我自己写了一个,并且返回值为false时表示此排列已经是降序排列了,也就是说:没有比这“更大的”的排列了,这里的“大”指的是字典序。
  时间复杂度为O(n!*n),其中n!表示最多有n!个排列,n表示每次生成下一个排列需要O(n)的时间复杂度。空间复杂度是O(1)。
 1 // 688144    zhuli19901106    1369    Accepted    点击此处查看所有case的执行结果    1020KB    1032B    60MS
 2 // 201401311639
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 
 8 void my_swap(char &x, char &y)
 9 {
10     char ch;
11 
12     ch = x;
13     x = y;
14     y = ch;
15 }
16 
17 void my_reverse(char s[], int ll, int rr)
18 {
19     if (ll >= rr) {
20         return;
21     }
22 
23     int i;
24     for (i = ll; i < ll + rr - i; ++i) {
25         my_swap(s[i], s[ll + rr - i]);
26     }
27 }
28 
29 bool my_next_permutation(char s[], int n)
30 {
31     int i, j;
32 
33     for (i = n - 1; i > 0; --i) {
34         if (s[i - 1] < s[i]) {
35             break;
36         }
37     }
38     if (i == 0) {
39         return false;
40     }
41     --i;
42 
43     for (j = n - 1; j > i; --j) {
44         if (s[i] < s[j]) {
45             my_swap(s[i], s[j]);
46             break;
47         }
48     }
49     my_reverse(s, i + 1, n - 1);
50 
51     return true;
52 }
53 
54 int main()
55 {
56     char s[20];
57     int n;
58 
59     while (scanf("%s", s) == 1) {
60         n = strlen(s);
61         sort(s, s + n);
62         while (true) {
63             puts(s);
64             if(!my_next_permutation(s, n)) {
65                 break;
66             }
67         }
68     }
69 
70     return 0;
71 }

 

 posted on 2014-02-05 21:22  zhuli19901106  阅读(325)  评论(0编辑  收藏  举报