面试题整理8 字符串的排列

来源:互联网 发布:淘宝农村服务站 编辑:程序博客网 时间:2024/05/21 22:43

《剑指offer》面试题28

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

分析:  当我看到这个题目,我首先想到字符串中字符有可能重复,这时候该怎么办,如果没有重复那就是将所有字符的排列打印出来,全排列也是不怎么好求的,再往下就不好想了;

            书中用了分治的思想,将大问题分解为小问题。此题中将一个字符串分解为两部分,第一部分为它的第一个字符,第二部分为后面的所有字符。

            求一个字符串的全排列,可以分两步:首先求出所有可能出现在第一个位置的字符,在字符串中可以采用把第一个字符与后面的所有字符交换的方法,如abc字符串中a分别于b、c交换,第一个位置的字符可能是a、b、c;第二步固定第一个字符,求后面字符的排列。如此递归,直到后面的字符为字符串尾。

           但是,书上的思路并没有考略字符串中字符重复的问题,如字符串aaa,按照上述思路,排列有6种,但实际上每种都是aaa,所以应该是只有一种。

           因此上述思路在我看来不是完全准确的,当把第一个字符与后面的字符交换时,首先应该判断两者是否相同,如果相同则跳过,因为已经处理过此种情况。

          但是这个思路同样是有问题的,如aabb,还是会出现重复的情况。。对于解决重复没有想到什么好方法。。。

          所以还是默认全排列就是所有字符不管是否相同的全排列。

代码:

         在函数中pStr指向整个字符串的第一个字符串,pBegin指向当前我们做排列操作的字符串的第一个字符。每一次递归从pBegin向后扫描每一个字符,交换两者后,再对pBegin后面的字符串递归地做排列操作。


void Permutation(char* pStr){    if(pStr == NULL)        return;    Permutation(pStr, pStr);}void Permutation(char* pStr, char* pBegin){    if(*pBegin == '\0')    {        printf("%s\n", pStr);    }    else    {        for(char* pCh = pBegin; *pCh != '\0'; ++ pCh)        {if( pCh == pBegin ){Permutation(pStr, pBegin + 1);continue;}/*if( *pCh == *pBegin )  //去除和第一个字符相同的{continue;}*/            char temp = *pCh;            *pCh = *pBegin;            *pBegin = temp;            Permutation(pStr, pBegin + 1);            temp = *pCh;            *pCh = *pBegin;            *pBegin = temp;        }    }}

0 0
原创粉丝点击