您的位置:首页 > 职场人生

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

2014-03-03 10:09 197 查看
《剑指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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: