字符串(力扣题库)

字符串

反转字符串(leetcode304题)

最简单方法直接用c++库:
1.strrev函数。(cstring)

#include 
#include 
using namespace std;
 
int main()
{
    string s="abcd";
 
    strrev(s);
 
    cout<<s<<endl;
 
    return 0;
}

2.reverse函数(algorithm)

#include 
#include 
#include 
using namespace std;
 
int main()
{
    string s = "abcd";
 
    reverse(s.begin(),s.end());
 
    cout<<s<<endl;
 
    return 0;
}

3.利用string构造函数(string)string容器,自带反转

#include 
#include 
#include 
using namespace std;
int main() {
	string s = "hello";
    cout<<string(s.rbegin(),s.rend())<<endl;//通过string构造函数,传入原字符串的逆向迭代器。
    return 0;
 }

为了减少直接调用库函数解决问题,采取了下列方法写出方法,通过swap字符反转

class Solution {
public:
    void reverseString(vector<char>& s) {
        //reverse(s.begin(),s.end());
        for(int i=0,j = s.size()-1;i<s.size()/2;i++,j--)
        {
            swap(s[i],s[j]);
        }
    }
};

也可以使用双指针法:(该方法和上述方法类似,基本是同理概念)

class Solution {
public:
    void reverseString(vector<char>& s) {
        //reverse(s.begin(),s.end());
        // for(int i=0,j = s.size()-1;i
        // {
        //     swap(s[i],s[j]);
        // }
        int n = s.size();
        for(int left =0,right = n-1;left<right;left++,right--)
        {
            swap(s[left],s[right]);
        }
    }
};

反转字符Ⅱ (leetcode541题)

最初思路: 我先进行判断,每2k个字符进行一次判断,在进行反转

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size(); i += (2*k))
        {
            if(i+k <= s.size())
            {
                reverse(s.begin()+i,s.begin()+i+k);
            }
            else
            {
                reverse(s.begin()+i,s.end());
            }
        }
        return s;
    }
};

更加简化版本,直接调用reverse和min库函数

class Solution {
public:
    string reverseStr(string s, int k) {
        int n = s.size();
        for(int i=0;i<s.size(); i += (2*k))
        {
            reverse(s.begin()+i,s.begin()+min(i+k,n));
        }
        return s;
    }
};

替换空格(leetcode LCR122(路劲加密))

1.暴力解法,遍历字符串,将需要替换的字符进行替换

class Solution {
public:
    string pathEncryption(string path) {
        int n = path.size();
        for(int i=0;i<n;i++)
        {
            if(path[i] == '.')
            {
                path[i] = ' ';
            }
        }
        return path;
    }
};

此方法有个弊端,倘若替换的字符数不等,该方法时有问题的

此时我将题目变换,比如 将 ‘.‘变换为’%20’:

class Solution {
public:
    string pathEncryption(string path) {
        // int n = path.size();
        // for(int i=0;i
        // {
        //     if(path[i] == '.')
        //     {
        //         path[i] = ' ';
        //     }
        // }
        // return path;
        //此处将 ‘。’换成为‘%20’
        int count =0;
        int sold = path.size();
        //判断需要增加格子数
        for(int i=0;i<sold;i++)
        {
            if(path[i] == '.')
            {
                count++;
            }
        }
        path.resize(sold+count*2);
        int snew = path.size();
        for(int i=snew-1,j=sold-1;j<i;i--,j++)
        {
            if(path[j] != '.')
            {
                path[i] = path[j]; 
            }
            else
            {
                path[i] = '0';
                path[i-1] = '2';
                path[i-2] = '%';
                i -= 2;
            }
        }
        return path;
    }
};

所以我们得先将数组扩展大小,在进行替换,从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

反转字符串中的单词(leetcode 152)

我的第一个思路是调用split库,后来发现思想出了问题,c++根本没有这个库,这是python常用的。
解题思路:
1.去除多余的空格,并且首位都没有空格
2.将字符进行反转
3.进行循环,当遇到空格,就将空格前的字符再反转

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 removeextra(string &s)
    {
        int slow = 0;
        for(int i=0; i<s.size();++i)
        {
            cout<<"第 i 次"<<i<<endl;
            if(s[i] != ' ')
            {
                if(slow != 0)
                {
                    s[slow++] = ' ';
                }
                while(i<s.size()&&s[i] != ' ')
                {
                    s[slow++] = s[i++];
                    cout<<"第2次"<<i<<endl;
                }
            }
        }
        s.resize(slow);
    }

    string reverseWords(string s) {
        removeextra(s);
        reverse(s,0,s.size()-1);
        int start = 0;
        for(int i =0;i<=s.size();++i)
        {
            if(i == s.size() || s[i] == ' ')
            {
                reverse(s,start,i-1);
                start = i+1;
            }
        }
        return s;

    }
};

再去除空格时,注意,双指针法去除。思想的对,一思想解万题。

动态口令(leetcode LCR182题)

解题思路:3此反转
字符串(力扣题库)_第1张图片

class Solution {
public:
    string dynamicPassword(string password, int target) {
        reverse(password.begin(),password.begin()+target);
        reverse(password.begin()+target,password.end());
        reverse(password.begin(),password.end());
        return password;
    }
};

但是呢,我没想到这个方法,我想法很暴力,建立新数组,进行填充。

class Solution {
public:
    string dynamicPassword(string password, int target) {
        reverse(password.begin(),password.begin()+target);
        reverse(password.begin()+target,password.end());
        reverse(password.begin(),password.end());
        return password;
    }
};

暴力还有第二种写法:更加简洁明了

class Solution {
public:
    string dynamicPassword(string password, int target) {
       int  n = password.size();
       string ans = {};
       for(int i = target;i<n;i++)
       {
           ans += password[i];
       }
        for(int i=0;i<target;i++)
        {
            ans += password[i];
        }
        return ans;

    }
};

当然,暴力方法提出了,正常思路也提出了,也可以偷懒,直接调用string库函数
此处使用substr和insert

class Solution {
public:
    string dynamicPassword(string password, int target) {
        string s1 = password.substr(0,target);
        string s2 = password.substr(target,password.size());
        s2.insert(password.size()-target,s1);
        return s2;

    }
};

实现 strStr() (leetcode 28题)

第一个思路,直接调用c++ string库函数,该方法可取,但是失去了学习数据结构算法的意义

class Solution {
public:
    int strStr(string haystack, string needle) {
        return haystack.find(needle);
    }
};

第二个思路,当然是无敌究极暴力解法:

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

KMP算法求解:soory,我没看懂,感兴趣可以直接搜索这个算法,find库函数原理也是来自于这个算法。

重复的子字符串(leetcode 459题)

利用库函数进行查询,你将字符串叠加再一起,再从1这个位置进行寻找,如果找到同样字符串且size()与原本相等,则存在。

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string t= s+s;
        return t.find(s,1) != s.size(); 
    }
};

KMP算法,还是那句话,我不会。。。。。。。

你可能感兴趣的:(leetcode,算法,c++)