1、最长公共子串
首先看最长公共子串的解答(暴力算法、动态规划、)
从优化到再优化,最长公共子串
2、最长公共子序列(LCS)
3、 leetcode 5 Longest Palindromic Substring 最长回文串
方法1:借助最长公共子串问题,将原来的string翻转,求两个字符串的最长公共子串,但是可能出现的情况是S=”abacdfgdcaba”, S′方法2:暴力算法
调出所有的子串比较是否是回文串
方法3: 动态规划
P(i,j) as following:
P(i,j)={true,false,if the substring Si…Sj is a palindromeotherwise.
true,
false,
if the substring
S
i
…
S
j
is a palindrome
otherwise.
P(i,j)=(P(i+1,j−1) and Sii
==Sjj
)P(i,i)=trueP(i,i+1)=(Sii
==Si+1i+1
)事件复杂度和空间复杂度都是n2
方法4: 自中心扩展 没有动态规划数组,时间复杂度仍然是n2,空间复杂度是1
每个字符串都有一个中心,一共有2n-1个中心。回文串是偶数的时候,中心在两个字符之间
class Solution {
public:
string longestPalindrome(string s) {
//使用第四个方法,自中心扩展
int start=0,end=0;//保存当前最长回文串的起始和终结位置
for(int i=0;i<s.size();i++)
{
int len1=expandFromCenter(s,i,i);//以当前字符为中心的回文串(奇数)
int len2=expandFromCenter(s,i,i+1);//以当前和下一个字符的中间为中心的回文串(偶数)
int len=max(len1,len2);
if(len>end-start+1)//如果求得的新字符串长度是比之前保存的要长的话
{
start=i-(len-1)/2;
end=i+len/2;
}
}
return s.substr(start,end-start+1);//注意这个函数的用法,是首地址和字符串的长度
}
int expandFromCenter(string& s,int left,int right){
while(left>=0&&right<=s.size()&&s[left]==s[right]){//这种书写方式考虑到奇数和偶数的情况
--left;
++right;
}
return right-left-1;//返回长度,因为right和left都是移到了回文串的外围位置
}
};
if i == j, then longest[i][j] = 1, naturally
if i+1 == j, then longest[i][j] = 2 if s[i] == s[j]
longest[i][j] = 1 otherwise
Transition rule:
- s[i] == s[j]
dp[i][j] = max(dp[i+1][j], dp[i][j-1], dp[i+1][j-1] + 2) - s[i] != s[j]
dp[i][j] = max(dp[i+1][j], dp[i][j-1], dp[i+1][j-1])
class Solution {
public:
//lhs means left hand side, rhs means right hand side
int longestPalindromeSubseq(string s) {
if (s.empty()) return 0;
vector<vector<int>> longest(s.size(), vector<int>(s.size()));
for (int len=1; len<=s.size(); len++) {
for (int lhs=0; lhs+len<=s.size(); lhs++) {
int rhs = lhs+len-1;
if (lhs == rhs) {
longest[lhs][rhs] = 1;
} else if (lhs+1 == rhs) {
longest[lhs][rhs] = (s[lhs] == s[rhs]) ? 2 : 1;
} else {
int add = s[lhs] == s[rhs] ? 2 : 0;
longest[lhs][rhs] = max(max(longest[lhs][rhs-1], longest[lhs+1][rhs]), longest[lhs+1][rhs-1] + add);
}
}
}
return longest[0].back();
}
};
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n=s.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=n-1;i>=0;i--)
{
dp[i][i]=1;
for(int j=i+1;j<n;j++)
{
if(s[i]==s[j])
dp[i][j]=dp[i+1][j-1]+2;
else
dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
}
}
return dp[0][n-1];
}
};
647. Palindromic Substrings 统计回文子串的个数
Given a string, your task is to count how many palindromic substrings in this string.
The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.
Example 1:
Input: "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c".
Example 2:
Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
Note:
- The input string length won't exceed 1000.
class Solution {
public:
int countSubstrings(string s) {
int sum=0;
int n=s.size();
if(n==0) return 0;
vector<vector<bool>> dp(n,vector<bool>(n,false));
for(int i=n-1;i>=0;i--)
{
dp[i][i]=true;
sum++;
for(int j=i+1;j<n;j++)
{
if(s[i]==s[j])
{
if(i+1==j||dp[i+1][j-1])
{
dp[i][j]=true;
sum++;
}
}
else dp[i][j]=false;
}
}
return sum;
}
};
214. Shortest Palindrome 最短回文串
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
For example:
Given "aacecaaa"
, return "aaacecaaa"
.
Given "abcd"
, return "dcbabcd"
.
Given two strings s and t, write a function to determine if t is an anagram of s.
For example,
s = "anagram", t = "nagaram", return true.
s = "rat", t = "car", return false.
Note:
You may assume the string contains only lowercase alphabets.
Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?
public:
bool isAnagram(string s, string t) {
vector<int> flag(256,0);
if(s.size()!=t.size()) return false;
for(int i=0;i<s.size();i++)
flag[s[i]]++;
for(int i=0;i<s.size();i++)
{
if(flag[t[i]]==0) return false;
flag[t[i]]--;
}
if(find_if(flag.begin(),flag.end(),com)!=flag.end()) return false;
return true;
}
static bool com(const int s){
return s>0?true:false;
}
};