优先算法——专题十一:字符串
最长公共前缀
14. 最长公共前缀 - 力扣(LeetCode)
两种方法:两两比较或者一起比较
class Solution {
public:
//两两比较,每次取出两个字符串的最长公共前缀作为基准和下一个进行比较,时间复杂度O(N*M)string longestCommonPrefix(vector<string>& strs) {string ans = strs[0];for(int i = 1; i < strs.size(); i++){int index = 0;while(index < ans.size() && index < strs[i].size()){if(ans[index] == strs[i][index])++index;elsebreak;}string tmp(ans.begin(), ans.begin() + index);ans = tmp;}return ans;}
};class Solution {
public:
所有字符串一起比较,当字符不同时,结束比较返回,时间复杂度也是O(M*N)string longestCommonPrefix(vector<string>& strs) {if(strs.size() == 0) return "" ;if(strs.size() == 1) return strs[0];int index = 0;int flag = 1;while(flag && index < strs[0].size()){char ch = strs[0][index];for(auto& str : strs){if(str == "")return "";if(index >= str.size()){flag = 0;break;}if(ch != str[index])flag = 0;}if(flag == 1)index++;}string ans(strs[0].begin(), strs[0].begin()+index);return ans;}
};
最长回文字符串
5. 最长回文子串 - 力扣(LeetCode)
中心扩展算法
class Solution {
public:
//中心扩展算法
//遍历,每次从当前元素向左右扩展比较
//注意奇数和偶数长度回文串的不同,所以比较起点不同string longestPalindrome(string s) {int n = s.size();int len = 0, prev = 0, next = 0;int anslen = 0, ansprev= 0, ansnext = 0;for(int i = 0; i < n; i++){//奇数处理prev = i;next = i;while(prev >= 0 && next < n && s[prev] == s[next]){prev--;next++;}len = next - prev - 1;if(len > anslen){anslen = len;ansprev = prev;ansnext = next;}//偶数处理prev = i;next = i + 1;while(prev >= 0 && next < n && s[prev] == s[next]){prev--;next++;}len = next - prev - 1;if(len > anslen){anslen = len;ansprev = prev;ansnext = next;}}return s.substr(ansprev + 1, anslen);}
};
二进制求和
67. 二进制求和 - 力扣(LeetCode)
大数相加或者相乘等都需要将字符串分为一个一个的数值进行运算
class Solution {
public:string addBinary(string a, string b) {//先翻字符串reverse(a.begin(), a.end());reverse(b.begin(), b.end());int p1 = 0, p2 = 0, len1 = a.size(), len2 = b.size();int tmp = 0;string ans;while(p1 < len1 || p2 < len2){int num1 = p1 < len1 ? a[p1] - '0' : 0;int num2 = p2 < len2 ? b[p2] - '0' : 0;int sum = num1 + num2 + tmp;tmp = sum / 2;sum %= 2;ans += sum + '0';p1++;p2++;}if(tmp) ans += tmp + '0';reverse(ans.begin(), ans.end());return ans;}
};
字符串相乘
43. 字符串相乘 - 力扣(LeetCode)
解法一:每位相乘之后求进位,相加结果
class Solution {
public:string multiply(string num1, string num2) {if(num1 == "0" || num2 == "0")return "0";int len1 = num1.size(), len2 = num2.size();reverse(num1.begin(), num1.end());reverse(num2.begin(), num2.end());string ans(len1 + len2, '0');for(int i = 0; i < len1; i++){//进行相乘string tmp(i, '0');int b = 0;//进位for(int j = 0; j < len2; j++){int a = (num1[i] - '0') * (num2[j] - '0') + b;b = a / 10;a %= 10;tmp += a + '0';}if(b)tmp += b + '0';b = 0;//将算出的字符串加到ans中int k = 0;for(k = 0; k < tmp.size(); k++){int a = ans[k] - '0' + tmp[k] - '0' + b;b = a / 10;a %= 10;ans[k] = a + '0';}for(k; k < ans.size() && b; k++){int a = ans[k] - '0' + b;b = a / 10;a %= 10;ans[k] = a + '0';}}while(ans.size() >= len1 + len2 && ans.back() == '0')ans.pop_back();reverse(ans.begin(), ans.end());return ans;}
};
解法二:每一步相乘之后放入数组下标位置,最后求进位
class Solution {
public:string multiply(string num1, string num2) {if(num1 == "0" || num2 == "0")return "0";int len1 = num1.size(), len2 = num2.size();reverse(num1.begin(), num1.end());reverse(num2.begin(), num2.end());vector<int> tmp(len1 + len2 - 1, 0);//无进位相乘for(int i = 0; i < len1; i++)for(int j = 0; j < len2; j++)tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');//处理进位string ans;int b = 0;for(int i = 0; i < tmp.size(); i++){int a = tmp[i] + b;b = a / 10;a %= 10;ans += a + '0';} if(b) ans += b + '0';reverse(ans.begin(), ans.end());return ans;}
};