前言
👧个人主页:@小沈YO.
😚小编介绍:欢迎来到我的乱七八糟小星球🌝
📋专栏:优选算法
🔑本章内容:字符串
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~
一、字符串示例
1.1 最⻓公共前缀
-
题⽬链接:14. 最⻓公共前缀
-
题⽬描述:
-
解法:
算法思路:
解法⼀(两两⽐较):
我们可以先找出前两个的最⻓公共前缀,然后拿这个最⻓公共前缀依次与后⾯的字符串⽐较,这样就可以找出所有字符串的最⻓公共前缀。
解法⼆(统⼀⽐较):
题⽬要求多个字符串的公共前缀,我们可以逐位⽐较这些字符串,哪⼀位出现了不同,就在哪⼀位截⽌。 -
C++代码
class Solution {
public:
string maxCommonPrefix(string& s1,string& s2)
{
int minlen=s1.size()<s2.size()?s1.size():s2.size();
string s;
for(int i=0;i<minlen;i++)
{
if(s1[i]==s2[i])s+=s1[i];
else break;
}
return s;
}
string longestCommonPrefix(vector<string>& strs)
{
string s=strs[0];
for(int i=1;i<strs.size();i++)
{
s=maxCommonPrefix(s,strs[i]);
}
return s;
}
};
--------------------------------------------------------------------------------------------
class Solution {
public:
string longestCommonPrefix(vector<string>& strs)
{
for(int i=0;i<strs[0].size();i++)
{
char tmp=strs[0][i];
for(int j=1;j<strs.size();j++)
{
if(i==strs[j].size()||tmp!=strs[j][i])return strs[j].substr(0,i);
}
}
return strs[0];
}
};
1.2 最⻓回⽂⼦串
- 题⽬链接:5. 最⻓回⽂⼦串
- 题⽬描述:
- 解法(中⼼扩散):
算法思路:
枚举每⼀个可能的⼦串⾮常费时,有没有⽐较简单⼀点的⽅法呢?
对于⼀个⼦串⽽⾔,如果它是回⽂串,并且⻓度⼤于 2,那么将它⾸尾的两个字⺟去除之后,它仍然是个回⽂串。此这样去除,⼀直除到⻓度⼩于等于 2 时呢?⻓度为 1 的,⾃⾝与⾃⾝就构成回⽂;⽽⻓度为 2 的,就要判断这两个字符是否相等了。
从这个性质可以反推出来,从回⽂串的中⼼开始,往左读和往右读也是⼀样的。那么,是否可以枚举回⽂串的中⼼呢?
从中⼼向两边扩展,如果两边的字⺟相同,我们就可以继续扩展;如果不同,我们就停⽌扩展。这样只需要⼀层 for 循环,我们就可以完成先前两层 for 循环的⼯作量。 - C++代码
class Solution {
public:
string longestPalindrome(string s)
{
//固定一个下标
int begin=0,len=0;
int left=0,right=0;
for(int i=0;i<s.size();i++)
{
left=i,right=i;
//做一次奇数长度扩展
while(left>=0&&right<s.size()&&s[left]==s[right])
{
left--;right++;
}
if(right-left-1>len)
{
len=right-left-1;
begin=left+1;
}
//偶数长度扩展
left=i,right=i+1;
while(left>=0&&right<s.size()&&s[left]==s[right])
{
left--;right++;
}
if(right-left-1>len)
{
len=right-left-1;
begin=left+1;
}
}
return s.substr(begin,len);
}
};
1.3 ⼆进制求和
- 题⽬链接:67. ⼆进制求和
- 题⽬描述:
- 解法(模拟⼗进制的⼤数相加的过程):
算法思路:
模拟⼗进制中我们列竖式计算两个数之和的过程。但是这⾥是⼆进制的求和,我们不是逢⼗进⼀,⽽是逢⼆进⼀。 - C++代码
class Solution {
public:
string addBinary(string a, string b)
{
string ret;
int n=a.size()-1,m=b.size()-1;
int sum=0;
while(n>=0||m>=0||sum)
{
if(n>=0)sum+=a[n--]-'0';
if(m>=0)sum+=b[m--]-'0';
ret+=to_string(sum%2);
sum/=2;
}
reverse(ret.begin(),ret.end());
return ret;
}
};
1.4 字符串相乘
- 题⽬链接:43. 字符串相乘
- 题⽬描述:
- 解法(⽆进位相乘然后相加,最后处理进位):
算法思路:
整体思路就是模拟我们⼩学列竖式计算两个数相乘的过程。但是为了我们书写代码的⽅便性,我们选择⼀种优化版本的,就是在计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕之后,再去考虑进位。如下图:
- C++代码
class Solution {
public:
string multiply(string num1, string num2)
{
//无进位相乘再相加
int n=num1.size(),m=num2.size();
vector<int> v(n+m-1);
reverse(num1.begin(),num1.end());
reverse(num2.begin(),num2.end());
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
int tmp=(num1[j]-'0')*(num2[i]-'0');
v[i+j]+=tmp;
}
}
int tmp=0,t=0;
string s;
while(tmp<n+m-1||t)
{
if(tmp<n+m-1)t+=v[tmp++];
s+=(t%10)+'0';
t/=10;
}
while(s.size()>1&&s.back()=='0')
s.pop_back();
reverse(s.begin(),s.end());
return s;
}
};