您的位置:首页 > 其它

回文字符串

2014-01-31 21:25 218 查看

题目描述:

回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。 输入:非空仅由小写字母组成的字符串,长度不超过100; 输出:能组成的所有回文串的个数(因为结果可能非常大,输出对1000000007取余数的结果)。 例如:输入"aabb" 输出为2(因为“aabb”对应的所有回文字符串有2个:abba和baab) 函数头部 c: int palindrome(const char *s); c++ int palindrome(const
string &s); java public static int palindrome(String s) ;

分析:哎,这题最要命的就是大整数处理问题 ,算小弟能力有限,只能用java完成这道题 ,因为如果用C的话处理大整数确实麻烦,而对于这道题简直是更加的麻烦。我没有更好的方法去完成,所以只能用java大整数,暴力解决,不过要注意时间复杂度的问题,要不然会超时。代码有注释,请信息看。不过在这里想说下这题的思路。其实这是一道地地道道的排列题目,但是并不是边排列边计数,而是通过找递推式子或者找出其中的规律,现在就让我们来找规律吧。

1、s=“aabb”;回文数counts=2!/(1!*1!);

2、s="aabbcc";回文数counts=3!/(1!*1!*1!);

3、s="aabbccc";回文数counts=3!/(1!*1!*1!);

4、s="aabbbbcc";回文数counts=4!/(1!*2!*1!);

5、s="aabbbcccc";回文数counts=4!/(1!*1!*2!);

.....

.....

.....

n、s;回文数counts=n/(c1!*c2!*......*c26!);

说明:n为字符串字符串s长度的一半,c1...26为字符串中某个字符个数的一半。它们的一般都是向下取整。

代码实现:

import java.math.BigInteger;
public class Main {
public static int palindrome(String s)
{
int[] counts = new int[26];
int i, j, k = 1, tk, p = 0, judge = 0, sum = 0, pp = 0, zero = 0, temp = 1;//声明一堆变量,judge判断字符串是否合法、sum为字符串总和、zero判断是否为单一字符,其他不解释了
char ss[] = s.toCharArray();
BigInteger allcounts = BigInteger.valueOf(1);
BigInteger eps = BigInteger.valueOf(0);
int len = s.length();
for (i = 0; i < 26; i++) counts[i] = 0;
for (i = 0; i < len; i++)//计算每种字符个数
{
counts[ss[i] - 'a']++;
}
for (i = 0; i < 26; i++)//判断字符串合法性
{
if (counts[i] % 2 == 1)
{
judge++;
}
if (counts[i] == 0)
{
zero++;
}//计数折半
counts[i] /= 2;
sum += counts[i];
}
if (zero == 25)//单一字符
{
return 1;
}
if (judge >= 2)//字符串不合法
{
return 0;
}
for (i = 1; i <= sum; i++)//计算阶乘
{
temp *= i;
if (temp >= 20000000 || i == sum)//这部很重要,减低时间复杂度
{
allcounts = allcounts.multiply(BigInteger.valueOf(temp));
temp = 1;
}
}
temp = 1;
for (i = 0; i<26; i++)//重复字符数阶乘
{
for (j = 1; j <= counts[i]; j++)
{
temp *= j;
if (temp >= 20000000 || j == counts[i])//这部很重要,减低时间复杂度
{
allcounts = allcounts.divide(BigInteger.valueOf(temp));//除去重复
temp = 1;
}
}
}

eps = allcounts.divide(BigInteger.valueOf(1000000007));//计算有多少个10000000007
allcounts = allcounts.add(eps.multiply(BigInteger.valueOf(-1000000007)));//对1000000007求余
return allcounts.intValue();
}

//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
public static void main(String args[])
{
System.out.println(palindrome("hqaymehhrsfuqrpahrimsxftuxqrpsejouuehaqtsryxjhearxmogmi"));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。

}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: