💁♂️个人主页:进击的荆棘
👇作者其它专栏:
相关题解
1.最长公共前缀
算法思路一(两两比较):
可以先找出前两个的最长公共前缀,然后拿这个最长公共前缀依次与后面的字符串比较,这样就可以找出所有字符串的最长公共前缀。
算法思路二(统一比较):
题目要求多个字符串的公共前缀,可以逐位比较这些字符串,哪一位出现了不同,就在哪一位截止。
cpp
//法一:两两比较
// class Solution {
// public:
// string longestCommonPrefix(vector<string>& strs) {
// string ret;
// ret=strs[0];
// for(int i=1;i<strs.size();i++){
// ret=Check(strs[i],ret);
// }
// return ret;
// }
// string Check(string& str,string& ret){
// int i=0;
// string cnt;
// for(int j=0;j<str.size()&&j<ret.size();j++){
// if(str[j]!=ret[j]) break;
// cnt+=str[j];
// }
// return cnt;
// }
// };
//法二:统一比较
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
for(int i=0;i<strs[0].size();i++){
char c=strs[0][i];
for(int j=0;j<strs.size();j++){
if(i==strs[j].size()||c!=strs[j][i])
return strs[0].substr(0,i);
}
}
return strs[0];
}
};
2.最长回文子串
算法思路(中心扩展):
枚举每一个可能的子串非常费时,可以采用中心扩展。
对于一个子串来说,若它是回文串,并且长度大于2,那么将它首尾的两个字母去掉之后,它仍然是一个回文串。如此这样去除,一直除到长度小于等于2时,就有两种情况。长度为1时,自身与自身就构成回文;而长度为2的,就要判断这两个字符是否相等。
从这个性质可以反推出来,从回文串的中心开始,往左读和往右读也是一样的。那么,是否可以枚举回文串的中心呢?
从中心向两边扩展,若两边的字母相同,就可以继续扩展;若不相同,就停止扩展。这样只需一直for循环,就可以完成先前两层for循环的工作量。
cpp
class Solution {
public:
string longestPalindrome(string s) {
int start=0,max_len=1;
//从中心扩展
for(int i=0;i<s.size()-1;i++){//依次枚举中点
//当最长回文子串为奇数时
int left=i-1,right=i+1;
while(left>=0&&right<s.size()){
if(s[left]==s[right]){
left--;
right++;
}
else break;
}
if(max_len<right-left-1){
max_len=right-left-1;
start=left+1;
}
//当最长回文子串为偶数时
left=i,right=i+1;
while(left>=0&&right<s.size()){
if(s[left]==s[right]){
left--;
right++;
}
else break;
}
if(max_len<right-left-1){
max_len=right-left-1;
start=left+1;
}
}
return s.substr(start,max_len);
}
};
3.二进制求和
算法思路(模拟十进制的大数相加的过程):
模拟十进制中的列竖式计算 两个数之和的过程。但是这里是二进制的求和,就不是逢十进一,而是逢二进一。
cpp
class Solution {
public:
string addBinary(string a, string b) {
string ret;
int i=a.size()-1,j=b.size()-1,t=0;
while(i>=0||j>=0||t){
if(i>=0) t+=a[i--]-'0';
if(j>=0) t+=b[j--]-'0';
ret+=t%2+'0';
//模拟进位
t/=2;
}
reverse(ret.begin(),ret.end());
return ret;
}
};
4.字符串相乘
算法思路(无进位相乘然后相加,最后处理进位):
整体思路就是模拟小学列竖式计算 两个数相乘的过程。但是为了书写代码的方便性,所以选择一种优化版本的,就是在**计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕后,再去考虑进位。**如下图:

cpp
//先算出每一位的值不进位,最后进位
class Solution {
public:
string multiply(string num1, string num2) {
int m=num1.size(),n=num2.size();
string ret;
vector<int> tmp(m+n-1);
//逆置
reverse(num1.begin(),num1.end());
reverse(num2.begin(),num2.end());
//算出每一位的值
for(int i=0;i<num1.size();i++){
for(int j=0;j<num2.size();j++){
tmp[i+j]+=(num1[i]-'0')*(num2[j]-'0');
}
}
//处理进位
int t=0,i=0;
while(i<m+n-1||t!=0){
if(i<m+n-1) t+=tmp[i++];
ret+=t%10+'0';
t/=10;
}
//处理前导零
while(ret.size()>1&ret.back()=='0') ret.pop_back();
reverse(ret.begin(),ret.end());
return ret;
}
};