classSolution { public: string multiply(string num1, string num2){ if (num1 == "0" || num2 == "0") { return"0"; } int n = num1.length() + num2.length(); vector<int> res(n); for (int i = num1.length() - 1; i >= 0; i--) { for (int j = num2.length() - 1; j >= 0; j--) { int sum = res[i + j + 1] + (num1[i] - '0') * (num2[j] - '0'); res[i + j + 1] = sum % 10; res[i + j] += sum / 10; } } string ans = ""; for (int i = 0; i < n; i++) { if (i == 0 && res[i] == 0) { continue; //去掉前置0 } ans += to_string(res[i]); } return ans; } };
这里也可以先像前面的题一样反转字符串以后再从前往后算,之后再倒回来。
8-4.累加数:306
1
9.字符串变换
9-1.Z字形变换:6
法一:压缩矩阵存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: string convert(string s, int numRows){ int n = s.length(), r = numRows; if (r == 1 || r == n) { return s; } vector<string> mat(r); for (int i = 0, x = 0, t = r * 2 - 2; i < n; i++) { mat[x] += s[i];//x记录行数 i % t < r - 1 ? ++x : --x;//第i%t行读取结束就继续下一行 } string ans; for (auto& row : mat) { ans += row; } return ans; } };
classSolution { public: string convert(string s, int numRows){ int n = s.length(), r = numRows; if (r == 1 || r == n) { return s; } string ans; int t = r * 2 - 2; //使得s[t]是第二个竖直列的第一个元素 for (int i = 0; i < r; i++) { for (int j = 0; j + i < n; j += t) { //遍历第i行的元素 ans += s[j + i]; if (i > 0 && i < r - 1 && j + t - i < n) { ans += s[j + t - i]; } } } return ans; } };
classSolution { public: string fillWords(vector<string>& words, int bg, int ed, int maxWidth, bool lastLine = false){ int wordCount = ed - bg + 1;//end减去begin后再加1 int spaceCount = maxWidth + 1 - wordCount; // 除去每个单词尾部空格, + 1 // 是最后一个单词的尾部空格的特殊处理 for (int i = bg; i <= ed; i++) { spaceCount -= words[i].size(); // 除去所有单词的长度 } int spaceSuffix = 1; // 词尾空格 int spaceAvg = (wordCount == 1) ? 1 : spaceCount / (wordCount - 1); // 额外空格的平均值 int spaceExtra = (wordCount == 1) ? 0 : spaceCount % (wordCount - 1); // 额外空格的余数 string ans; for (int i = bg; i < ed; i++) { ans += words[i]; // 填入单词 if (lastLine) { // 特殊处理最后一行 fill_n(back_inserter(ans), 1, ' '); continue; } fill_n(back_inserter(ans), spaceSuffix + spaceAvg + ((i - bg) < spaceExtra), ' '); // 根据计算结果补上空格 } ans += words[ed]; // 填入最后一个单词 fill_n(back_inserter(ans), maxWidth - ans.size(), ' '); // 补上这一行最后的空格 return ans; } vector<string> fullJustify(vector<string>& words, int maxWidth){ vector<string> ans; int cnt = 0; int bg = 0; for (int i = 0; i < words.size(); i++) { cnt += words[i].size() + 1; if (i + 1 == words.size() || cnt + words[i + 1].size() > maxWidth) { // 如果是最后一个单词,或者加上下一个词就超过长度了,即可凑成一行 ans.push_back( fillWords(words, bg, i, maxWidth, i + 1 == words.size())); bg = i + 1; cnt = 0; } } return ans; } };
10.字符串匹配(难度较高)
10-1.找出字符串中第一个匹配项的下标:28
法一:暴力匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: intstrStr(string haystack, string needle){ int n = haystack.size(), m = needle.size(); for (int i = 0; i + m <= n; i++) { bool flag = true; for (int j = 0; j < m; j++) { if (haystack[i + j] != needle[j]) { flag = false; break; } } if (flag) { return i; } } return-1; } };
使用substr与之同理:
substr()的时间复杂度为$O(n)$,空间复杂度是$O(1)$.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: intstrStr(string haystack, string needle){ for (int i = 0; i < haystack.size(); i++) { if (haystack[i] == needle[0]) { //第一个字符是否相等再决定是不是要尝试匹配整个字符串 string x = haystack.substr(i, needle.size()); if (x == needle) { return i; } } } return-1; } };
classSolution { public: intstrStr(string haystack, string needle){ int n = haystack.size(), m = needle.size(); if (m == 0) { return0; } vector<int> next(m); // 计算出next数组 for (int i = 1, j = 0; i < m; i++) { while (j > 0 && needle[i] != needle[j]) { j = next[j - 1]; } if (needle[i] == needle[j]) { j++; } next[i] = j; } // 根据next数值进行匹配 for (int i = 0, j = 0; i - j < n; i++) { // b 开始匹配的位置是否超过第一个叠加的 a while (j > 0 && haystack[i % n] != needle[j]) { //i%n,因为可能是多个haystack重复 j = next[j - 1]; } if (haystack[i % n] == needle[j]) { j++; } if (j == m) { return i - m + 1; } } return-1; }
intrepeatedStringMatch(string a, string b){ int an = a.size(), bn = b.size(); int index = strStr(a, b); if (index == -1) { return-1; } if (an - index >= bn) { return1; } return (bn + index - an - 1) / an + 2; } };
voidRabinKarp(char t[], char p[]) { int t_len = strlen(t); int p_len = strlen(p);
// 哈希滚动之用 int h = 1; for (int i = 0; i < p_len - 1; i++) h = (h * BASE) % MODULUS;
int t_hash = 0; int p_hash = 0; for (int i = 0; i < p_len; i++) { t_hash = (BASE * t_hash + t[i]) % MODULUS; p_hash = (BASE * p_hash + p[i]) % MODULUS; }
int i = 0; while (i <= t_len - p_len) { // 考虑到哈希碰撞的可能性,还需要用 memcmp 再比对一下 if (t_hash == p_hash && memcmp(p, t + i, p_len) == 0) cout << p << " is found at index " << i << endl;
classSolution { public: intexpandAroundCenter(const string& s, int left, int right){ int ans = 0; while (left >= 0 && right < s.size() && s[left] == s[right]) { --left; ++right; ++ans; } return ans; }
intcountSubstrings(string s){ int left = 0, right = 0, ans = 0; for (int i = 0; i < s.size(); i++) { ans +=expandAroundCenter(s, i, i) + expandAroundCenter(s, i, i + 1); } return ans; } };