给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
首先我直接采用了最暴力的解法,从头到尾依次比较,时间复杂度为O(n^3),代码如下:
string longestPalindrome(string s) {
if(s.size()<=0) return "";
if(s.size()==1) return s;
int start=0,maxLength=1;
for(int i=0;i<s.size();i++){
for(int j=i+1;j<s.size();j++){
int temp1,temp2;
for(temp1=i,temp2=j;temp1<temp2;temp1++,temp2--){
if(s[temp1]!=s[temp2]){
break;
}
}
if(temp1>=temp2&&j-i+1>maxLength){
maxLength=j-i+1;
start=i;
}
}
}
return s.substr(start,maxLength);
}
系统不通过,运行时间超时。
然后学习了动态规划算法,代码如下:
string longestPalindrome(string s) {
if(s.size()<=0) return "";
int len=s.size(),start=0,longest=1;
vector<vector<int>> dp(len,vector<int>(len));
for(int i=0;i<len;i++){
dp[i][i]=1;
}
for(int i=0;i<len-1;i++){
if(s[i]==s[i+1]){
dp[i][i+1]=1;
start=i;
longest=2;
}
}
for(int l=3;l<=len;l++){
for(int i=0;i<len-l+1;i++){
int j=i+l-1;
if(s[i]==s[j]&&dp[i+1][j-1]==1){
dp[i][j]=1;
start=i;
longest=l;
}
}
}
return s.substr(start,longest);
}
总结:通过这道题,学习了动态规划的思想。总结下来主要有如下几点:
1、最优子结构
2、子问题重叠
3、边界
4、子问题独立
5、备忘录
6、时间分析
在这里感谢下面的博客:
https://www.cnblogs.com/mini-coconut/p/9074315.html
http://www.cnblogs.com/sdjl/articles/1274312.html(动态规划写的非常经典)
这是我模仿写的金矿模型的代码:
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
const int max_n=100;
const int max_people=10000;
int n;
int peopleTotal;
int peopleNeed[max_n];
int gold[max_n];
int maxGold[max_people][max_n];
void init(){
ifstream inputFile("/home/adnois/CLionProjects/untitled/beibao.dat",ios::in);
if(!inputFile){
cout<<"cannot open"<<endl;
exit(1);
}
inputFile>>peopleTotal>>n;
for(int i=0;i<n;i++){
inputFile>>peopleNeed[i]>>gold[i];
}
inputFile.close();
for(int i=0;i<=peopleTotal;i++){
for(int j=0;j<n;j++){
maxGold[i][j]=-1;
}
}
}
int GetMaxGold(int people,int mineNum){
int retMaxGold;
if(maxGold[people][mineNum]!=-1){
retMaxGold=maxGold[people][mineNum];
}
else if(mineNum==0){
if(people>=peopleNeed[mineNum]){
retMaxGold=gold[mineNum];
}
else{
retMaxGold=0;
}
}
else if(people>=peopleNeed[mineNum]){
retMaxGold=max(GetMaxGold(people-peopleNeed[mineNum],mineNum-1)+gold[mineNum],GetMaxGold(people,mineNum-1));
}
else{
retMaxGold=GetMaxGold(people,mineNum-1);
}
maxGold[people][mineNum]=retMaxGold;
return retMaxGold;
}
int main(){
init();
cout<<GetMaxGold(peopleTotal,n-1);
}