回文字符串
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为字符串中某个字符个数的一半。它们的一般都是向下取整。
代码实现:
题目描述:
回文字符串是指从左到右和从右到左相同的字符串,现给定一个仅由小写字母组成的字符串,你可以把它的字母重新排列,以形成不同的回文字符串。 输入:非空仅由小写字母组成的字符串,长度不超过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 //提示:自动阅卷结束唯一标识,请勿删除或增加。 }