leetcode : Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

首先还是分析问题,分析问题得到思路再分析思路的复杂度非常重要!!!!!!

首先动态规划,最开始使用用int 二维数组dp[i][j]表示ij之间的回文串长度,超内存。

后来发现如果是回文串,长度就是j-i,把int改成bool,不超内存了,超时。。。

后来想着用容器效率不如数组高,就用动态数组,结果超内存!!!!后来仔细一想,恩内存泄露了。。申请了没delete。。。测试的case多了内存就没了,

另外,动态数组并不是真正的数组,所以速度上较之vector感觉提升不会特别大,总之提升肯定没直接用数组大。

所以最后直接申请了个1001 * 1001的数组,AC

 

更重要的是,后来看答案,用看起来特别2的朴素方法,遍历0-n,分别以每个可能的位置作为回文串中心,向两边找最大回文串,速度是动态规划的4倍左右。。

但是如果分析时间复杂度两者都是n^2啊,而且中心扩散法并没有查找任何一个重复元素,相对的,比动态规划省去了读写数组的时间,以及剩下了二维数组所占用的空间。

 

但是在最少回文分割问题中,用动态规划就能AC,不用反而会超时。与上面问题不同的关键在于求i-j是否为回文串的顺序不同,最少回文分割的求dp[i][j]子问题的顺序导致前后出现重复,而中心扩散法恰好是无重复的遍历了每一种情况,所以在时间跟空间上都完爆了动态规划。

 

另外,set 不一定就比unordered_set快(需要性能测试的!!),动态规划也不一定比备忘录慢(递归开销很大的!!!)

AC代码(动态规划):

class Solution {
public:
    string longestPalindrome(string s) {
        //vector<vector<bool>> dp(s.size() + 1, vector<bool>(s.size() + 1, false));
        bool dp[1001][1001] = {0};
        int max = INT_MIN;
        int start = 0, end = 0;
        for(int i = s.size(); i >0; --i){
            for(int j = s.size(); j >=i; --j){
                if(j - i <= 1){
                    dp[i][j] = s[i - 1] == s[j - 1];
                }else{
                    dp[i][j] = dp[i + 1][j - 1] && s[i - 1] == s[j - 1];
                }
                if(dp[i][j]){
                    if(max < j - i + 1){
                        max = j - i + 1;
                        start = i;
                        end = j;
                    }
                }
            }
        }
        return s.substr(start - 1,end - start + 1);
    }
    
};

 

posted on 2014-12-23 21:28  远近闻名的学渣  阅读(155)  评论(0)    收藏  举报

导航