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); } };
浙公网安备 33010602011771号