• 字符串-算法总结


    目录

    反转字符串

    替换空格

    翻转字符串里的单词

    左旋字符串

    KMP

    重复的字符字串



    反转字符串

    原理:

    对于字符串在原地翻转问题,可以reverse。但是其本质我们可以知道是利用双指针方法。一个指向开始,一个指向结束,不断交换两个指针的值,这里交换可以用swap,或者中间变量交换。

    代码如下:

    1. class Solution {
    2. public:
    3. void reverseString(vector<char>& s) {
    4. int left = 0;
    5. int right = s.size() - 1;
    6. char temp;
    7. while (left < right)
    8. {
    9. swap(s[left],s[right]);
    10. left++;
    11. right--;
    12. }
    13. }
    14. };

    相关题目:
    344. 反转字符串 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-string/541. 反转字符串 II - 力扣(LeetCode)https://leetcode.cn/problems/reverse-string-ii/

    替换空格

    方法:

    我们主要是先计算出扩充之后的大小,以及从后遍历数组解决数据不移动问题。

    统计需要扩充的大小

    1. int count = 0;
    2. int oldWidth = s.size();
    3. for(int i = 0; i < s.size(); i++){
    4. if(s[i] == ' '){
    5. count++;
    6. }
    7. }
    8. int newWidth = s.size() + count * 2;
    9. s.resize(newWidth);

    定义两个指针,一个是旧数组末尾,一个是新数组末尾。如果不是空格,两个同时--。当遇到空格,新指针一次性移动三位,并且填充三位。

    1. //从后往前遍历
    2. for(int i = oldWidth - 1, j = newWidth - 1; i < j; j--, i--){
    3. if(s[i] != ' '){
    4. s[j] = s[i];
    5. }
    6. else{
    7. s[j] = '0';
    8. s[j - 1] = '2';
    9. s[j - 2] = '%';
    10. j -= 2;
    11. }

    完整代码:

    1. class Solution {
    2. public:
    3. string replaceSpace(string s) {
    4. int count = 0;
    5. int oldWidth = s.size();
    6. for(int i = 0; i < s.size(); i++){
    7. if(s[i] == ' '){
    8. count++;
    9. }
    10. }
    11. int newWidth = s.size() + count * 2;
    12. s.resize(newWidth);
    13. //从后往前遍历
    14. for(int i = oldWidth - 1, j = newWidth - 1; i < j; j--, i--){
    15. if(s[i] != ' '){
    16. s[j] = s[i];
    17. }
    18. else{
    19. s[j] = '0';
    20. s[j - 1] = '2';
    21. s[j - 2] = '%';
    22. j -= 2;
    23. }
    24. }
    25. return s;
    26. }
    27. };

    相关题目:

    剑指 Offer 05. 替换空格 - 力扣(LeetCode)https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

    翻转字符串里的单词

    方法:

    思路为:去除空格,翻转字符串,对每个单词再进行翻转。

    去除空格:双指针实现。首先遍历整个字符串。当遇到非‘ ’时,把快指针遍历的元素插入慢指针对应的下标。

    注意:我们对于中间的单词是需要空格的,因此我们会在不是第一个起始位置的地方插入一个空格,然后开始后续的插入非空格元素。

    翻转字符串:遍历字符串,利用swap进行交换

    单词翻转:利用计数器。遍历整个字符串,当计数器遇到单词边界或者字符串边界时,翻转计数器对应的单词。然后更新计数器,继续找下一个单词。

    整个代码如下:

    1. class Solution {
    2. public:
    3. void reverse(string& s, int start, int end){ //翻转,区间写法:左闭又闭 []
    4. for(int i = start, j = end; i < j; i++, j--){
    5. swap(s[i], s[j]);
    6. }
    7. }
    8. void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间添加空格, 快慢指针。
    9. int slow = 0;
    10. for(int i = 0;i < s.size(); i++){
    11. if(s[i] != ' '){
    12. if(slow != 0){
    13. s[slow++] = ' ';
    14. }
    15. while(i < s.size() && s[i] != ' ' ){
    16. s[slow++] = s[i++];
    17. }
    18. }
    19. }
    20. return s.resize(slow);
    21. }
    22. string reverseWords(string s) {
    23. removeExtraSpaces(s);//去除空格
    24. reverse(s, 0, s.size()-1);//翻转
    25. //翻转单词
    26. int start = 0;
    27. for(int i = 0; i <= s.size(); i++){
    28. if(i == s.size() || s[i] == ' '){
    29. //当i移动到边界或者碰到单词边界
    30. reverse(s, start, i - 1);
    31. start = i + 1;
    32. }
    33. }
    34. return s;
    35. }
    36. };

    相关题目:
    151. 反转字符串中的单词 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-words-in-a-string/

    左旋字符串

    方法:

     按照上图进行翻转即可。

    1. class Solution {
    2. public:
    3. string reverseLeftWords(string s, int n) {
    4. reverse(s.begin(), s.begin() + n);
    5. reverse(s.begin() + n , s.end());//左闭右开
    6. reverse(s.begin(), s.end());
    7. return s;
    8. }
    9. };

    KMP

    1.当遇到不匹配时,根据前缀表找到最长相等前后缀后,只需要从前面那个位置重新开始找,因为重新找的位置满足了前面的相同。

    1. class Solution {
    2. public:
    3. void getNext(int* next,const string&s){
    4. int j=0;
    5. next[0]=0;
    6. for(int i=1;isize();i++){
    7. //把j回退到next数组下标的地方
    8. while(j>0&&s[i]!=s[j]){
    9. j=next[j-1];
    10. }
    11. //相同的话,j就前移继续判断
    12. if(s[i]==s[j]){
    13. j++;
    14. }
    15. next[i]=j;
    16. }
    17. }
    18. int strStr(string haystack, string needle) {
    19. if(needle.size()==0){
    20. return 0;
    21. }
    22. int next[needle.size()];
    23. getNext(next,needle);
    24. int j=0;
    25. for(int i=0;isize();i++){
    26. while(j>0&&haystack[i]!=needle[j]){
    27. j=next[j-1];
    28. }
    29. if(haystack[i]==needle[j]){
    30. j++;
    31. }
    32. if(j==needle.size()){
    33. return(i-needle.size()+1);
    34. }
    35. }
    36. return -1;
    37. }
    38. };

    重复的字符字串

    1. class Solution {
    2. public:
    3. bool repeatedSubstringPattern(string s) {
    4. //find返回的s的首字母下标
    5. //find返回时,如果是不能重复的,则返回大小比原来大1
    6. //如果可以重复,则返回大小比原来下
    7. return (s + s).find(s, 1) < s.size();
    8. }
    9. };

  • 相关阅读:
    java 整理
    官网下载JAVA的JDK11版本(下载、安装、配置环境变量)
    阿里云OSS图床搭建方法
    使用php 获取时间今天、明天、昨天时间戳的详解
    GPT-4论文精读【论文精读·53】
    华为云安全亮相世界互联网大会
    肖sir___面试就业课程____app
    微服务效率工具 goctl 深度解析(上)
    《数字图像处理-OpenCV/Python》连载(2)目录
    Linux 生成大文件
  • 原文地址:https://blog.csdn.net/m0_60524373/article/details/126933155