1. Question 5 of the longest palindrome substring force deduction
Substring: substring must be continuous, which is different from the concept of subsequence
Subsequence:
Where the violent solution can be optimized: palindromes are judged only when the length of the substring is > the current maximum length,
Is there anything that can be improved
class Solution { public: bool ishuiwen(string s){ if(s.size()==1) return true; int i=0; int j=s.size()-1; while(i<=j){ if(s[i]!=s[j]){ return false; } ++i; --j; } return true; } string longestPalindrome(string s) { int n=s.size(); int maxlength=0; int res_i=0; int i=0; for(;i<n;++i){ for(int len=1;len<=n-i;++len){ cout<<"i="<<i<<" len="<<len<<endl; if(len>maxlength){ string temp=s.substr(i,len); if(ishuiwen(temp)){ res_i=i; maxlength=len; } } } } cout<<"res_i="<<res_i<<" maxlength="<<maxlength<<endl; return s.substr(res_i,maxlength); } };
Dynamic programming solution: note that maxlength is initialized to 1, otherwise the use case "ac" cannot pass. It finally passes. Then, you need to pay attention to the condition that J-I < 3 j-i+1<4.
The length between double pointer mode I and j is j-i+1, If the length is less than 4, the possible length is 1,2,3. Under this else, s[i]==s[j], then it must be a palindrome substring
The reason why maxlength here should be initialized with 1?? Because in the following two nested for loops, maxlength may not be updated and still maintain the value of 0, which will produce incorrect results
You can also perform a separate processing on a string with length 2?? Maybe
class Solution { public: string longestPalindrome(string s) { if(s.size()<2) return s; int n=s.size(); vector<vector<int>> dp(n,vector<int>(n)); // In this case, all are initialized to 0// int dp[n][n]; //i. J represents the left and right boundary state transition equation DP [i] [J] = 1 respectively. If (s [i] = = s [J] & & dp[i+1] DP [) for the substring with length of 2 or 3 with J-I < 3, the value of dp[i+1] [j-1] is not required for(int i=0;i<n;++i){//This piece is wrong!! dp[i][i]=1; } int maxlength=1, res_i=0; for(int j=1;j<n;++j){ for(int i=0;i<j;++i){ if(s[i]!=s[j]){ dp[i][j]=0; } else{ if(j-i<3){ dp[i][j]=1; } else{ if(dp[i+1][j-1]==1){ dp[i][j]=1; } } } if(j-i+1>maxlength && dp[i][j]==1){ res_i=i; maxlength=j-i+1; } } } return s.substr(res_i,maxlength); } };
2. Longest common substring
Find the longest common substring for two strings
str1.find(str2) find str2 in str1. See the records on Youdao cloud notes
There is another way of violence,
You can remember this writing, using two pointers i and j Two more pointers m and k
while(m<length1 && k<length2 &&str1[m]==str2[k]) The key to this sentence is that we need to guarantee the legitimacy of M and K
#include <iostream> #include <string> using namespace std; int main() { string str1,str2; str1="helloworld"; str2="loop"; //cin>>str1; //cin>>str2; int length1=str1.size(), length2=str2.size(); int m,k,len,maxlength=0,res_i; for(int i=0;i<length1;++i){ for(int j=0;j<length2;++j){ m=i; k=j; len=0; while(m<length1 && k<length2 &&str1[m]==str2[k]){ ++m; ++k; ++len; } if(len>maxlength){ maxlength=len; res_i=i; } } } cout<<maxlength<<endl; cout<<str1.substr(res_i,maxlength); //cout << "Hello world!" << endl; return 0; }
Solution of dynamic programming 1:
In fact, it is better not to name the array below this solution dp
In order to get results over and over again, some optimization should be done
class Solution { public: /** * longest common substring * @param str1 string String the string * @param str2 string String the string * @return string character string */ string LCS(string str1, string str2) { // write code here int m=str1.size(), n=str2.size(); vector<vector<int>> dp(m,vector<int>(n,0)); for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ if(str1[i]==str2[j]){ dp[i][j]=1; } } } int maxlength=0,res_i=0; for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ int temp=0; int u=i, v=j; while(u<m && v<n && dp[u][v]==1){ ++temp; ++u; ++v; } if(temp>maxlength){ maxlength=temp; res_i=i; } } } return str1.substr(res_i,maxlength); } };
Improve:
if(str1[i]!=str2[j]){
dp[i][j]=0;}
else{
if(i==0 || j==0) dp[i][j]=1;
else dp[i-1][j-1]+1;
}
3. Longest common subsequence
It also needs to use the solution of dynamic programming. 1. Determine the meaning of dp array and subscript. 2 2. Determine the state transition equation
class Solution { public: int longestCommonSubsequence(string text1, string text2) { int m=text1.size(); int n=text2.size(); string a="@"; text1=a+text1; cout<<text1<<endl; text2=a+text2; vector<vector<int>> dp(m+1,vector<int>(n+1,0)); for(int i=1;i<m+1;++i){ for(int j=1;j<n+1;++j){ if(text1[i]==text2[j]){ dp[i][j]=dp[i-1][j-1]+1; } else{ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } for(auto i:dp){ for(auto j:i){ cout<<j<<" "; } cout<<endl; } return dp[m][n]; } };
4. The sliding window algorithm to be used is:
Minimum window substring
Given two strings S and T, find the length of the shortest continuous substring containing all characters of T in S