字符串处理

无重复字符的连续子串个数

/**
 * @description: 给定一个字符串,输出无重复字符的连续字串的个数
 * @param {*}
 * @return {*}
 */
int GetCountOfSubString(string &input)
{
    string::size_type len = input.size();
    vector<string> res;
    size_t result = 1;
    for (string::size_type i = 0; i < len; i++) {
        string s(1, input[i]);
        for (string::size_type j = i + 1; j < len; j++) {
            if (s.find(input[j]) != string::npos) {
                break;
            }
        s = s + input[i];
        ++result;
        }
    }
}

字符串的排列

/**
 * @description: 剑指 Offer 38. 字符串的排列
 * 输入一个字符串,打印出该字符串中字符的所有排列。
 * 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
 * @param {*}
 * @return {*}
 */
class Solution {
public:
    vector<string> rec;
    void backtrack(const string& s, int i, int n, string& perm) {
        if (i == n) {
            rec.push_back(perm);
            return;
        }
        for (int j = 0; j < n; j++) {
            if (vis[j] || (j > 0 && !vis[j - 1] && s[j - 1] == s[j])) {
                continue;
            }
            vis[j] = true;
            perm.push_back(s[j]);
            backtrack(s, i + 1, n, perm);
            perm.pop_back();
            vis[j] = false;
        }
    }

    vector<string> permutation(string s) {
        int n = s.size();
        vis.resize(n);
        sort(s.begin(), s.end());
        string perm;
        backtrack(s, 0, n, perm);
        return rec;
    }
};

class Solution {
public:
    vector<string> permutation(string s) {
        string path;
        visited.resize(s.size());
        sort(s.begin(), s.end()); // 按照字典序排序,以处理重复的字符
        dfs(s, path);
        sort(res.begin(), res.end()); // 按照字典序排序
        return res;
    }

    void dfs(string &s, string &path)
    {
        // 终止条件,当path中元素个数与s中个数相等时结束,搜索结束
        if (path.size() == s.size()) {
            res.push_back(path);
            return;
        }

        // 做选择
        for (string::size_type i = 0; i < s.size(); ++i) {
            if (visited[i] || (i > 0 && s[i - 1] == s[i] && !visited[i-1])) { // 排除不合法选择(剪枝)
                continue;
            }
            visited[i] = true;
            path.push_back(s[i]);
            dfs(s, path);
            // 回退
            visited[i] = false;
            path.pop_back(); // string也有这个操作
        }
        return;
    }
private:
    vector<string> res;
    vector<bool> visited;
};

【LeetCode 9】 回文数

/**
 * @description: 9.回文数
 * @param {*}
 * @return {*}
 */
class Solution {
public:
    bool isPalindrome(int x) {
        string s1(to_string(x));
        string s2(s1);
        reverse(s1.begein(), s1.end());
        return s1 == s2 ? true : false;
    }
};

字符串编码最小长度

/*
给定一个单词列表,我们将这个列表编码成一个索引字符串S与一个索引列表A。
例如,如果这个列表是[“time”, “me”, “bell”],我们就可以将其表示为S = "time#bell#“和indexes = [0, 2, 5]。
对于每一个索引,我们可以通过从字符串 S 中索引的位置开始读取字符串,直到”#"结束,来恢复我们之前的单词列表。
那么成功对给定单词列表进行编码的最小字符串长度是多少呢?
输入:words = ["time", "me", "bell"]
输出:10
说明:S = “time#bell#” , indexes = [0, 2, 5]
提示:

1 <= words.length <= 2000
1 <= words[i].length <= 7
每个单词都是小写字母。
思路:这题的难点在于读懂题目以及提炼题目内容。显然,当某个单词被另一个单词包含的时候,那么它就是不需要出现在索引中的单词,
问题的关键在于怎么处理单词之间的包含关系。通过观察可以发现,当所有单词反转并排序之后,若存在包含关系,则被包含的单词一定是它下一个单词的子串,利用这个关系,思路就出来了。
反转字符串,对全部字符串排序,遍历字符串判断当前字符串是否为下一个字符串的子串。值得注意的是,对string使用find方法,当能够找到的时候,将返回子串第一个起始位置的索引,若不能找到,
则返回string的end迭代器。
*/

#include<string>
#include<algorithm>
#include <iostream>
#include <vector>

using namespace std;
class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        int n = words.size();
        vector<string> reverWord;
        for (auto word : words) {
            reverse(word.begin(), word.end());
            reverWord.push_back(word);
        }
        int minLen = 0;
        sort(reverWord.begin(), reverWord.end());
        for (int i = 0; i < n; i++) {
            if (i < n - 2 && reverWord[i + 1].find(reverWord[i]) != string::npos) {
                continue;
            } else {
                minLen += reverWord[i].size() + 1;
            }
        }
        return minLen;
    }
};

int main()
{
    Solution S;
    vector<string> input{"tmei", "me", "bell"};
    int res = S.minimumLengthEncoding(input);
    cout << res << endl;
}

翻转字符串

/*
食堂便利店购置了一台LED滚屏,只能显示大写字母与小写字母组成的句子 str。句中每个单词的首字母均大写,之后的字符为小写。
为实现特定滚动效果,请你帮忙编写一个函数,找出想显示的句子中的每个单词,然后将其逐个反转,且不改变原单词的大小写,最终将全部反转好的单词进行拼接,并返回该字符串。

示例 1:
输入:str = "MyNameIsTom"
输出:"yMemaNsImoT"
解释:str中的单词为”My”,“Name”,“Is”,“Tom”
示例 2:
输入:str = "LowLL"
输出:"woLLL"
解释:str 中的单词为“Low”,“L”,“L”
限制:

1 <= str的长度 <= 100000
str由26个小写英文字母及26个大写英文字母组成
str[0] 为大写字母。
思路:这题的题意不难理解,反转字符串中的每个单词,而每个单词都是以大写字母开始,因此通过遍历字符串,将大写字母作为单词分割的判断条件,关键在于如何保存当前大写字母的前一个单词。
解法1:逐个处理字符,使用临时的字符串来保存字符。该解法需要对最后一个单词进行特殊处理,因为最后一个单词的终止条件不是遇到大写字母,而是访问到了字符串的最后一个字符。
*/
#include<string>
#include<algorithm>
#include <iostream>

using namespace std;

class Solution {
public:
    string reverseSentence(string inputStr)
    {
        if (inputStr.empty()) {
            return "";
        }
        string word;
        word.push_back(inputStr[0]); // word += inputStr[0];
        string res;
        for (string::size_type i = 1; i < inputStr.size(); i++) {
            if (isupper(inputStr[i]) || i == inputStr.size() - 1) {
                if (i == inputStr.size() - 1 ) { 
                    word.push_back(inputStr[i]);
                }
                reverse(word.begin(), word.end());
                res.append(word);
                word.clear();
            }
            word.push_back(inputStr[i]);
        }
        return res;
    }
};

int main()
{
    Solution S;
    string input("ILoveChina");
    string s = S.reverseSentence(input);
    cout << s << endl;
}

【LeetCode 151】翻转字符串里的单词

https://blog.csdn.net/weixin_43892514/article/details/121585150

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值