[leetcode]Longest Palindromic Substring

 此题我曾经做过类似的(http://hi.baidu.com/lautsie/item/459a182eeddc568e6f2cc34a)但还是忘了,可见这个算法还是很tricky的。其实O(n^2)的算法还是能想到的,就是遍历每个字符,然后从该字符向两旁扩,寻找最长子串。但居然有O(n)的方法,见下面链接。

http://www.felix021.com/blog/read.php?2040

最后的代码其实可以做优化,比如最后不需要再遍历一边p[],但复杂度不变,又不是关键,就这样吧~

public class Solution {

    public String longestPalindrome(String s) {

        // Start typing your Java solution below

        // DO NOT write main() function

        StringBuilder sb = new StringBuilder();

        sb.append('#');

        for (int i = 0; i < s.length(); i++)

        {

            sb.append(s.charAt(i));

        	sb.append('#');

        }

        

        String ss = sb.toString();

        int[] p = new int[ss.length()];

        int mx = 0;

        int id = 0;

        for (int i = 0; i < ss.length(); i++)

        {

        	p[i] = mx > i ? Math.min(p[id * 2 -i], mx - i) : 1;

        	while (i+p[i] < ss.length() && i - p[i] >=0)

        	{

        		if (ss.charAt(i + p[i]) == ss.charAt(i-p[i]))

        		{

        			p[i]++;

        		}

        		else

        		{

        			break;

        		}

        	}

        	if (i + p[i] > mx)

        	{

        		mx = i + p[i];

        		id = i;

        	}

        }

        

        // process result

        int maxIndex = 0;

        int maxLen = 0;

        for (int i = 0; i < ss.length(); i++)

        {

        	if( p[i] > maxLen)

        	{

        		maxLen = p[i];

        		maxIndex = i;

        	}

        }

        StringBuilder r = new StringBuilder();

        for (int i = maxIndex - p[maxIndex] + 1; i <= maxIndex + p[maxIndex] - 1; i++)

        {

        	if(ss.charAt(i) != '#')

        	{

        		r.append(ss.charAt(i));

        	}

        }

        return r.toString();

    }

}

第二刷,不强求用Manacher方法。使用n^2的方法,要注意长度为奇数和偶数两种情况。

class Solution {

public:

    string longestPalindrome(string s) {

        int maxLen = 0;

        int idx = 0;

        for (int i = 0; i < s.length(); i++)

        {

            for (int len = 0; i - len >= 0 && i+len < s.length(); len++)

            {

                if (s[i-len] != s[i+len])

                    break;

                if (maxLen < len * 2 + 1)

                {

                    maxLen = len * 2 + 1;

                    idx = i - len;

                }

            }

            for (int len = 0; i - len >= 0 && i+len+1 < s.length(); len++)

            {

                if (s[i-len] != s[i+len+1])

                    break;

                if (maxLen < (len + 1) * 2)

                {

                    maxLen = (len + 1) * 2;

                    idx = i - len;

                }

            }

        }

        return s.substr(idx, maxLen);

    }

};

  

你可能感兴趣的:(substring)