前言
快要开学了,由于已经整整三四个月没动代码了,码力归0了,花了几天时间把前面的题重新刷了一遍,研一有课也不太能去实习,正好趁此机会继续提高!
151. 反转字符串中的单词
- 移除多余空格(双指针法,)
- 将整个字符串反转(反转字符串,左闭右开)
- 将每个单词反转(空格和最后就翻转)
-
class Solution { public: void reverse(string& s, int start, int end){ // 翻转,区间写法:左闭右闭 [] for (int i = start, j = end; i < j; i++, j--) { swap(s[i], s[j]); } } void removeExtraSpaces(string& s) {// 去除所有空格并在相邻单词之间添加空格, 快慢指针。 int slow = 0; // 整体思想参考https://programmercarl.com/0027.移除元素.html for (int i = 0; i < s.size(); ++i) { if (s[i] != ' ') { // 遇到非空格就处理,即删除所有空格。 if (slow != 0) s[slow++] = ' '; // 手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。 while (i < s.size() && s[i] != ' ') { // 补上该单词,遇到空格说明单词结束。 s[slow++] = s[i++]; } } } s.resize(slow); // slow的大小即为去除多余空格后的大小。 } string reverseWords(string s) { removeExtraSpaces(s); // 去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。 reverse(s, 0, s.size() - 1); int start = 0; // removeExtraSpaces后保证第一个单词的开始下标一定是0。 for (int i = 0; i <= s.size(); ++i) { if (i == s.size() || s[i] == ' ') { // 到达空格或者串尾,说明一个单词结束。进行翻转。 reverse(s, start, i - 1); // 翻转,注意是左闭右闭 []的翻转。 start = i + 1; // 更新下一个单词的开始下标start } } return s; } };
剑指 Offer 58 - II. 左旋转字符串
- 局部反转 + 整体反转,比模拟简单而且空间复杂度只有O(1)
-
class Solution { public: string reverseLeftWords(string s, int n) { reverse(s.begin(), s.begin() + n); reverse(s.begin() + n, s.end()); reverse(s.begin(), s.end()); return s; } };
28. 找出字符串中第一个匹配项的下标
- KMP算法理论理解看视频最浅显易懂的 KMP 算法讲解_哔哩哔哩_bilibili
- next数组生成图示
- 以下版本为【next数组版:前缀表统一减1】
-
class Solution { public: void getNext(int* next, const string& s) { int j = -1; next[0] = j; for(int i = 1; i < s.size(); i++) { // 注意i从1开始 while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同了 j = next[j]; // 向前回退 } if (s[i] == s[j + 1]) { // 找到相同的前后缀 j++; } next[i] = j; // 将j(前缀的长度)赋给next[i] } } int strStr(string haystack, string needle) { if (needle.size() == 0) { return 0; } int next[needle.size()]; getNext(next, needle); int j = -1; // // 因为next数组里记录的起始位置为-1 for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始 while(j >= 0 && haystack[i] != needle[j + 1]) { // 不匹配 j = next[j]; // j 寻找之前匹配的位置 } if (haystack[i] == needle[j + 1]) { // 匹配,j和i同时向后移动 j++; // i的增加在for循环里 } if (j == (needle.size() - 1) ) { // 文本串s里出现了模式串t return (i - needle.size() + 1); } } return -1; } };
后言
KMP算法理解起来真是让人头大,明天开完组会再看看然后模仿着写一下吧~