Careercup - Facebook面试题 - 5177378863054848

2014-05-02 08:29

题目链接

原题:

Write a function for retrieving the total number of substring palindromes. 

For example the input is 'abba' then the possible palindromes= a, b, b, a, bb, abba 

So the result is 6. 



Updated at 11/11/2013: 

After the interview I got know that the O(n^3) solution is not enough to go to the next round. It would have been better to know before starting implementing the solution unnecessarily ...

题目:给定一个字符串,统计所有回文子串的个数。O(n^3)的算法是明显的暴力算法,当然要被淘汰了。

解法1:一个简单的优化,是O(n^2)的。从每个位置向两边计算有多少个回文串。这样可以用O(1)空间,O(n^2)时间完成算法。

代码:

 1 // http://www.careercup.com/question?id=5177378863054848

 2 #include <iostream>

 3 #include <string>

 4 #include <vector>

 5 using namespace std;

 6 

 7 int countPalindrome(const string &s)

 8 {

 9     int n = (int)s.length();

10     if (n <= 1) {

11         return n;

12     }

13     

14     int i, j;

15     int res;

16     int count;

17     

18     res = 0;

19     for (i = 0; i < n; ++i) {

20         j = 0;

21         count = 0;

22         while (i - j >= 0 && i + j <= n - 1 && s[i - j] == s[i + j]) {

23             ++count;

24             ++j;

25         }

26         res += count;

27         

28         j = 0;

29         count = 0;

30         while (i - j >= 0 && i + 1 + j <= n - 1 && s[i - j] == s[i + 1 + j]) {

31             ++count;

32             ++j;

33         }

34         res += count;

35     }

36     

37     return res;

38 }

39 

40 int main()

41 {

42     string s;

43 

44     while(cin >> s) {

45         cout << countPalindrome(s) << endl;

46     }

47 

48     return 0;

49 }

解法2:有个很巧妙的回文串判定算法,叫Manacher算法,可以在O(n)时间内找出最长回文字串的长度。这题虽然是统计个数,同样可以用Manacher算法搞定。Manacher算法中有个很重要的概念,叫“最长回文匹配半径”,意思是当前最长回文子串能覆盖到的最靠右的位置。每当我们检查的中心位置处于这个半径之内时,就可以和另一边的对称点进行参照,减少一些重复的扫描。如果处于半径之外,就按照常规的方式向两边扫描了。Manacher算法的思想一两句话很难说清楚,在此提供一个链接吧:Manacher算法处理字符串回文

代码:

  1 // http://www.careercup.com/question?id=5177378863054848

  2 // Modified Manacher Algorithm

  3 #include <algorithm>

  4 #include <ctime>

  5 #include <iostream>

  6 #include <string>

  7 #include <vector>

  8 using namespace std;

  9 

 10 class Solution {

 11 public:

 12     long long int countPalindrome(const string &s) {

 13         int n = (int)s.length();

 14         

 15         if (n <= 1) {

 16             return n;

 17         }

 18         

 19         preProcess(s);

 20         n = (int)ss.length();

 21         int far;

 22         int far_i;

 23         

 24         int i;

 25 

 26         far = 0;

 27         c[0] = 0;

 28         for (i = 1; i < n; ++i) {

 29             c[i] = 1;

 30             if (far > i) {

 31                 c[i] = c[2 * far_i - i];

 32                 if (far - i < c[i]) {

 33                     c[i] = far - i;

 34                 }

 35             }

 36             

 37             while (ss[i - c[i]] == ss[i + c[i]]) {

 38                 ++c[i];

 39             }

 40             

 41             if (i + c[i] > far) {

 42                 far = i + c[i];

 43                 far_i = i;

 44             }

 45         }

 46         

 47         long long int count = 0;

 48         for (i = 0; i < n; ++i) {

 49             count += (c[i] + (i & 1)) / 2;

 50         }

 51         

 52         ss.clear();

 53         c.clear();

 54         

 55         return count;

 56     }

 57 private:

 58     string ss;

 59     vector<int> c;

 60     

 61     void preProcess(const string &s) {

 62         int n;

 63         int i;

 64         

 65         n = (int)s.length();

 66         ss.clear();

 67         // don't insert '#' here, index may go out of bound.

 68         ss.push_back('$');

 69         for (i = 0; i < n; ++i) {

 70             ss.push_back(s[i]);

 71             ss.push_back('#');

 72         }

 73         c.resize(ss.length());

 74     };

 75 };

 76 

 77 int main()

 78 {

 79     string s;

 80     Solution sol;

 81     const int big_n = 500000;

 82 

 83     s.resize(big_n);

 84     for(int i = 0; i < big_n; ++i) {

 85         s[i] = 'a';

 86     }

 87     

 88     clock_t start, end;

 89     start = clock();

 90     cout << sol.countPalindrome(s) << endl;

 91     end = clock();

 92     cout << "Runtime for test case of size " << big_n << ": " 

 93          << (1.0 * (end - start) / CLOCKS_PER_SEC) 

 94          << " seconds." << endl;

 95 

 96     while (cin >> s) {

 97         cout << sol.countPalindrome(s) << endl;

 98     }

 99     

100     return 0;

101 }

 

你可能感兴趣的:(Facebook)