27. 移除元素 - 力扣(LeetCode)

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int Slow=0;
        for(int Fast=0;Fast<size(nums);Fast++)
        {
            if(nums[Fast]!=val){
                nums[Slow]=nums[Fast];
                Slow++;
            }
            
        }return Slow;
    }
};

151. 反转字符串中的单词 - 力扣(LeetCode)

//题目描述:反转一个句子中的单词顺序,去除多余的空格。
/*思路: 1.先去除句子开头空格;
        2.将多个空格缩减为一个空格。
        3.去除结尾空格;
      实现:
            1.当是第一个下标,走;
            2.快指针往前走,如果连续两个字符是空格,则跳出循环?
            
              */
#include<iostream>
#include<string>    
using namespace std;
class Solution {
public:
    void removeExtraSpaces(string &s) {
        
        int Slow=0;
        int Fast=0;
        while(Fast==0&&s[Fast]==' ')
        {Fast++;}
        for(;Fast<size(s);Fast++)
        {
            if (s[Fast]==' '&&s[Fast-1]==' ')
            {
            continue;//跳过连续的空格
            }
            else 
            {s[Slow]=s[Fast];
            Slow++;
            }
        }
            if(Slow-1>0&&s[Slow-1]==' ')
            {s.resize(Slow-1);}
            else
            {s.resize(Slow);}
        
    }
    void reverse(string & s,int start,int end){
        int j;
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
        
    }
    string reverseWords(string s)
    {
        removeExtraSpaces(s);
        reverse(s,0,size(s)-1);
        int start=0;
        for(int i=0;i<=size(s);++i)
        {        
            if(i==size(s)||s[i]==' '){
                reverse(s,start,i-1);
                start =i+1;
            }
        }
        return s;
    }
};
int main(){
    Solution sol;
    string s="  the   sky  is blue  ";
    string result=sol.reverseWords(s);
    cout<<result<<endl;
    return 0;
}

字符串总结:

反转一个单词--用头尾两个指针交换;

反转前k个单词-----增加了边界的判断;

反转字符串中的单词----去首尾和重复空格+整体反转+遇到空格反转单词。

找出字符串与给定字串第一个匹配字符的下标。

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

题目描述:返回串中给定字串的第一个下标

暴力解法:

相当于我拿着一个needle框去对haystack进行比对。

class Solution {
public:
    int strStr(string haystack, string needle) {
        for (int i = 0; i < haystack.size(); i++) {
            int j;
            for (j=0; j < needle.size(); j++) {
                if (i + j >= haystack.size() || haystack[i + j] != needle[j]) {
                    break;
                }
            }
            if (j==needle.size())
            return i;
    }return -1;
    }

KMP算法思路:

1.开始匹配(使用for循环往前走);如果没对上;

2.求next数组;

3.从next数组最大值下标开始的位置继续匹配;

如何求next数组?

1.初始化;

2.前后缀相同;

3.前后缀不相同;

4.更新next的值。

next数组本质上是一个对数组的每一个下标位置进行类加的操作,因此使用for(i)循环,最后的目的一定是更新next[i]。

下面的重点就是如何表示相同前后缀的个数。

首先明确这是作用于模板串(needle)的。

next[i]表示的是从next[0]开始,截止该位(包含它本身),字符串的相同前后缀的个数。

毫无疑问,next[0]=0;

next[1],aa;  1

next[2],aab;  0

next[3], aaba;  1

我们要建立的是字符串下标----字符串相同前后缀的个数之间的关系。

为什么可以通过前缀末尾位和后缀末尾位来表示相同前后缀的个数呢?()

因为在一个长度大于1的字符串中,我们比较的第一个:前缀是一定是字符串的第一位,后缀是字符串的最后一位, 我们比较的第二个 

以s[3]  :aaba 为例,a和a,true;aa和ba,false;aab和aba,false;s[3]=1;

其中,如果长度为2的字符串不匹配,那么后面的长度为3的一定不匹配(?)//顺着想不下去了

逆着走代码试试:

初始化:next[0]=0;

循环第一步:i=0;j=0;s[i]=s[j]=a;next[1]=1;

第二步:i=2;j=1;s[i]=b;s[j]=a;j=0;next[2]=0;

第三步:i=3;j=0;j++=1;next[3]=1;

第四步:i=4;j=1;j++ =2;next[4]=2;

void getNext(int* next, const string& s) {
    int j = 0;
    next[0] = 0;
    for (int i = 1; i < s.size(); i++) {
        while (j > 0 && s[i] != s[j]) {
            j = next[j - 1];
        }
        if (s[i] == s[j]) {
            j++;
        }
        next[i] = j;
    }
}
}

后面还有整体逻辑,候补。

459. 重复的子字符串 - 力扣(LeetCode)

给定一个字符串,判断其是否可由重复的字串构成。

暴力解法思路: 

 

posted on 2025-11-13 23:16  FAfa_C++  阅读(27)  评论(0)    收藏  举报