目录
一、最长公共前缀

解法一:两两比较

class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int n=strs.size();
string ret=strs[0];
for(int i=1;i<n;++i)
{
int cur=0;
while(cur<=strs[i-1].size()&&cur<=strs[i].size())
{
if(ret[cur]==strs[i][cur])
{
++cur;
}
else
{
ret=ret.substr(0,cur);
break;
}
}
}
return ret;
}
};
解法二:统一比较
问题在于如何 统一,嵌套for循环就行,外界变量绑定第几个元素,内的变量绑定行数

class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int n=strs.size(),cur=0;
for(int i=0;i<strs[0].size();++i)
{
for(int j=1;j<strs.size();++j)
{
if(i>strs[j].size()||strs[0][i]!=strs[j][i])
{
//如果不符合了,cur存的是上一次符合的末尾,直接return
return strs[0].substr(0,cur);
}
}
//所有的字符串都遍历完了,代表cur位置符合,++cur
++cur;
}
return strs[0];
}
};
二、最长回文子串

解法一:中心扩展算法
基于回文特性,使用中心扩展算法,即先固定一个中心,再开始往左右找
注意substr参数,s.substr(起始下标,长度)
我说之前做到这题怎么脑海里总有种思路是从后往前遍历,然后在遍历的位置往左右拓展,这就复习到了,真好,感觉这种思路也相当于是一种暴力吧
class Solution {
public:
string longestPalindrome(string s) {
int begin=0,len=0,left,right;
for(int i=0;i<s.size();++i)
{
//奇数长度子串
left=right=i;
while(left>=0&&right<=s.size()-1&&s[left]==s[right])
{
--left;
++right;
}
if(right-left-1>len)
{
begin=left+1;
len=right-left-1;
}
//偶数长度子串
left=i,right=i+1;
while(left>=0&&right<=s.size()-1&&s[left]==s[right])
{
--left;
++right;
}
if(right-left-1>len)
{
begin=left+1;
len=right-left-1;
}
}
return s.substr(begin,len);
}
};
解法二:dp
在dp:回文串系列中详细介绍了dp解决回文串问题的解法总结,感兴趣的可以点点主页到专栏看看。附链接:动规:回文串问题-优快云博客
dp[i][j]表示i~j闭区间,是否是回文串,判断是不是就从两端不断往内,
如果s[i]==s[j],如果i==j,返回true,如果i恰好是j左边一个数也就是i+1==j返回true
其他情况就要看dp[i+1][j-1],因为需要后边的数据,所以i层需要倒着填。
class Solution {
public:
string longestPalindrome(string s) {
int n=s.size(),len=0,begin=0;
vector<vector<bool>> dp(n,vector<bool>(n));
for(int i=n-1;i>=0;--i)
{
for(int j=i;j<n;++j)
{
if(s[i]==s[j])dp[i][j]=i+1<j?dp[i+1][j-1]:true;
if(dp[i][j]&&len<j-i+1)
{
len=j-i+1;begin=i;
}
}
}
return s.substr(begin,len);
}
};
三、二进制求和

模拟加法,逢二进一,无需多言。
注意是字符形式,所以取数要-'0',ret+=num+'0',这一块很容易出错
相信聪明的你一定很快就会写出来了♪(^∇^*)
class Solution {
public:
string addBinary(string a, string b) {
//从最低位开始
int cur1=a.size()-1,cur2=b.size()-1,t=0;
string ret;
while(cur1>=0||cur2>=0||t)
{
if(cur1>=0)t+=a[cur1--]-'0';
if(cur2>=0)t+=b[cur2--]-'0';
ret+=t%2+'0';
t/=2;
}
reverse(ret.begin(),ret.end());
return ret;
}
};
四、字符串相乘

高精度乘法,没什么好说的。
解法一:模拟竖式乘法
class Solution {
public:
string multiply(string num1, string num2) {
if(num1=="0"||num2=="0")
{
return "0";
}
int m=num1.size(),n=num2.size();
vector<int>ans(m+n,0);
for(int i=m-1;i>=0;--i)
{
for(int j=n-1;j>=0;--j)
{
//i,j位存在结果数组的i+j+1位
int mul=(num1[i]-'0')*(num2[j]-'0');
int sum=mul+ans[i+j+1];
ans[i+j+1]=sum%10;
//处理进位
ans[i+j]+=sum/10;
}
}
string ret;
for(int num:ans)
{
//处理前导零
if(!(ret.empty()&&num==0))
{
ret+=num+'0';
}
}
return ret;
}
};
优化解法一,最后再处理进位

class Solution {
public:
string multiply(string num1, string num2) {
int m=num1.size(),n=num2.size();
//因为先不考虑进位,所以我们只需要开m+n-1大小即可
vector<int> arr(m+n-1);
for(int i=m-1;i>=0;--i)
{
for(int j=n-1;j>=0;--j)
{
//i,j位置映射到i+j位置
arr[i+j]+=(num1[i]-'0')*(num2[j]-'0');
}
}
string ret;
int cur=m+n-2,t=0;
while(cur>=0||t)
{
if(cur>=0)t+=arr[cur--];
ret+=t%10+'0';
t/=10;
}
while(ret.size()>1&&ret.back()=='0')ret.pop_back();
reverse(ret.begin(),ret.end());
return ret;
}
};
此篇完。

被折叠的 条评论
为什么被折叠?



