最长回文子串
来源:互联网 发布:linux ntpclient 编辑:程序博客网 时间:2024/06/17 19:09
1 题目
Given a stringS, find the longest palindromic substring in S. You may assume that the maximumlength of S is 1000, and there exists one unique longest palindromic substring.
2 分析
若字符串str为对称串则称str为回文 (palindromic) 串;若str中子串subStr为对称串,则subStr为str的回文子串。例如字符串str=”abbacde”,其中子串subStr=”abba”为回文子串,且str中不存在比subStr更长的回文子串,则subStr为str的最长回文子串。
2.1 一个比较笨的想法
最长公共子串:给定两个字符串,求出它们之间最长的相同子字符串的长度。因此可以先求出题目中字符串s的逆向字符串rs,然后求s与rs的最长公共子串,但是此时公共子串必须满足在s中的位置与在rs中的位置相对应。
此时问题的时间复杂度与最长公共子串相同。
另外,[http://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html]给出了时间复杂度为O(n)的算法,研究中……
2.2 直接法
从字符串中的每一个位置开始正向与逆向遍历比较以此为中心的回文子串的长度。该方法的求解时间复杂度为O(n2)。
3 实现
(1) 最长公共子串参考http://www.cnblogs.com/ider/p/longest-common-substring-problem-optimization.html,实现如下:
string longestPalindrome(strings){ string result; string rs; int size = s.size(); while (size > 0) { rs.push_back(s[--size]); } int lenth = 0; int pos = findLongestCommanSubString(s,rs, lenth); while (lenth-- > 0) { result.push_back(s[pos++]); } return result;} int findLongestCommanSubString(conststring &s1, const string &s2, int &lenth){ int pos = 0; int size1 = s1.size(); int size2 = s2.size(); if (0 == size1 || 0 == size2) { return 0; } vector<vector<int> > table(2,vector<int>(size2, 0)); int comparisons = 0; for (int j = 0; j < size2; ++j) { ++comparisons; if (s1[0] == s2[j]) { table[0][j] = 1; if (0 == lenth) { lenth = 1; pos = 0; } } } for (int i = 1; i < size1; ++i) { int cur = ((i & 1) == 1); int pre = ((i & 1) == 0); table[cur][0] = 0; if (s1[i] == s2[0]) { table[cur][0] = 1; if (0 == lenth) { lenth = 1; pos = i; } } for (int j = 1; j < size2; ++j) { if (s1[i] == s2[j]) { table[cur][j] =table[pre][j - 1] + 1; if (lenth <table[cur][j]) { if (size1 - i- 1 == j - table[cur][j] + 1) { lenth =table[cur][j]; pos = i- lenth + 1; } } } else { table[cur][j] = 0; } } } return pos;}
(2) 对应2.2,代码如下:
string longestPalindrom(strings){ int l, r; l = r = 0; int len = s.size(); int start = 0; int maxLen = 0; if (len <= 1) { return s; } int tempLen = 0; for (int i = 0; i < len; ++i) { l = i - 1; r = i + 1; tempLen = 1; while (l >= 0 && r <=len - 1 && s[l] == s[r]) { tempLen += 2; if (tempLen > maxLen) { start = l; maxLen = tempLen; } --l; ++r; } l = i; r = i + 1; tempLen = 0; while (l >= 0 && r <=len - 1 && s[l] == s[r]) { tempLen += 2; if (tempLen > maxLen) { start = l; maxLen = tempLen; } --l; ++r; } } string res = s.substr(start, maxLen); return res;}
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 窗口缩放导致页面排版错乱的解决方法
- 【GDOI】8.22训练总结
- SQL基本语法
- 使用joystick控制arduino调试电机
- spring JDBC 查询没有目标的方法
- 最长回文子串
- ECMAScript6学习笔记《二》-----“const命令与let命令”
- POJ 1330 ---(线段树在线LCA 与 tarjan离线LCAs)
- TextView和EditText的总结 (收藏)
- Jetty学习(三)--jetty部署spring mvc项目
- hdu 5419 Victor and Toys 线段树成段更新
- Ubuntu下安装搜狗输入法
- android Bitmap内存优化(一) Bitmap 详解
- 找出二叉树中某两个结点的第一个公共祖先