力扣水题:字符串

目录

187. 重复的DNA序列

246. 中心对称数

293. 翻转游戏

408. 有效单词缩写

412. Fizz Buzz

604. 迭代压缩字符串

734. 句子相似性

1065. 字符串的索引对

1119. 删去字符串中的元音

1180. 统计只含单一字母的子串

1662. 检查两个字符串数组是否相等

1684. 统计一致字符串的数目

1704. 判断字符串的两半是否相似

1768. 交替合并字符串

1796. 字符串中第二大的数字

1805. 字符串中不同整数的数目

1807. 替换字符串中的括号内容

1813. 句子相似性 III

1814. 统计一个数组中好对子的数目

2042. 检查句子中的数字是否递增

2185. 统计包含给定前缀的字符串

2283. 判断一个数的数字计数是否等于数位的值

2287. 重排字符形成目标字符串

2299. 强密码检验器 II

2309. 兼具大小写的最好英文字母

2496. 数组中字符串的最大值

2710. 移除字符串中的尾随零

2828. 判别首字母缩略词

2864. 最大二进制奇数


187. 重复的DNA序列

DNA序列 由一系列核苷酸组成,缩写为 'A''C''G' 和 'T'.。

  • 例如,"ACGAATTCCG" 是一个 DNA序列 。

在研究 DNA 时,识别 DNA 中的重复序列非常有用。

给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。你可以按 任意顺序 返回答案。

示例 1:

输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC","CCCCCAAAAA"]

示例 2:

输入:s = "AAAAAAAAAAAAA"
输出:["AAAAAAAAAA"]

提示:

  • 0 <= s.length <= 105
  • s[i]=='A''C''G' or 'T'
class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        map<string,int>m;
        for(int i=0;i+10<=s.length();i++){
            m[s.substr(i,10)]++;
        }
        vector<string>ans;
        for(auto &mi:m)if(mi.second>1)ans.push_back(mi.first);
        return ans;
    }
};

246. 中心对称数

中心对称数是指一个数字在旋转了 180 度之后看起来依旧相同的数字(或者上下颠倒地看)。

请写一个函数来判断该数字是否是中心对称数,其输入将会以一个字符串的形式来表达数字。

示例 1:

输入: num = "69"
输出: true
示例 2:

输入: num = "88"
输出: true
示例 3:

输入: num = "962"
输出: false
示例 4:

输入:num = "1"
输出:true

class Solution {
public:
    bool isStrobogrammatic(string num) {
        map<char,char>m;
        m['1']='1',m['0']='0',m['8']='8',m['6']='9',m['9']='6';
        for(int i=0;i<=num.length()/2;i++)if(m[num[i]]!=num[num.length()-i-1])return false;
        return true;
    }
};

293. 翻转游戏

你和朋友玩一个叫做「翻转游戏」的游戏。游戏规则如下:

给你一个字符串 currentState ,其中只含 '+' 和 '-' 。你和朋友轮流将 连续 的两个 "++" 反转成 "--" 。当一方无法进行有效的翻转时便意味着游戏结束,则另一方获胜。

计算并返回 一次有效操作 后,字符串 currentState 所有的可能状态,返回结果可以按 任意顺序 排列。如果不存在可能的有效操作,请返回一个空列表 [] 。

示例 1:

输入:currentState = "++++"
输出:["--++","+--+","++--"]
示例 2:

输入:currentState = "+"
输出:[]
 

提示:

1 <= currentState.length <= 500
currentState[i] 不是 '+' 就是 '-'

class Solution {
public:
    vector<string> generatePossibleNextMoves(string cs) {
         vector<string>ans;
         for(int i=1;i<cs.length();i++){
             if(cs[i]=='+'&&cs[i-1]=='+'){
                cs[i]='-',cs[i-1]='-';
                ans.push_back(cs);
                cs[i]='+',cs[i-1]='+';
             }
         }
         return ans;
    }
};

408. 有效单词缩写

字符串可以用 缩写 进行表示,缩写 的方法是将任意数量的 不相邻 的子字符串替换为相应子串的长度。例如,字符串 "substitution" 可以缩写为(不止这几种方法):

  • "s10n" ("s ubstitutio n")
  • "sub4u4" ("sub stit u tion")
  • "12" ("substitution")
  • "su3i1u2on" ("su bst i t u ti on")
  • "substitution" (没有替换子字符串)

下列是不合法的缩写:

  • "s55n" ("s ubsti tutio n",两处缩写相邻)
  • "s010n" (缩写存在前导零)
  • "s0ubstitution" (缩写是一个空字符串)

给你一个字符串单词 word 和一个缩写 abbr ,判断这个缩写是否可以是给定单词的缩写。

子字符串是字符串中连续的非空字符序列。

示例 1:

输入:word = "internationalization", abbr = "i12iz4n"
输出:true
解释:单词 "internationalization" 可以缩写为 "i12iz4n" ("i nternational iz atio n") 。

示例 2:

输入:word = "apple", abbr = "a2e"
输出:false
解释:单词 "apple" 无法缩写为 "a2e" 。

提示:

  • 1 <= word.length <= 20
  • word 仅由小写英文字母组成
  • 1 <= abbr.length <= 10
  • abbr 由小写英文字母和数字组成
  • abbr 中的所有数字均符合 32-bit 整数范围
class Solution {
public:
    bool validWordAbbreviation(string word, string abbr) {
        if(abbr.empty())return word.empty();
        if(abbr[0]>='a'&&abbr[0]<='z'){
            if(word.empty() || word[0]!=abbr[0])return false;
            word=word.substr(1,word.length()-1);
            abbr=abbr.substr(1,abbr.length()-1);
            return validWordAbbreviation(word, abbr);
        }
        int len=1,x=abbr[0]-'0';
        if(x==0)return false;
        if(abbr.length()>1 && abbr[1]>='0'&&abbr[1]<='9'){
            len=2,x=x*10+abbr[1]-'0';
        }
        if(x==0 || x>word.length())return false;
        word=word.substr(x,word.length()-x);
        abbr=abbr.substr(len,abbr.length()-len);
        if(!abbr.empty() && abbr[0]>='0'&&abbr[0]<='9')return false;
        return validWordAbbreviation(word, abbr);
    }
};

412. Fizz Buzz

给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer下标从 1 开始)返回结果,其中:

  • answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。
  • answer[i] == "Fizz" 如果 i 是 3 的倍数。
  • answer[i] == "Buzz" 如果 i 是 5 的倍数。
  • answer[i] == i (以字符串形式)如果上述条件全不满足。

示例 1:

输入:n = 3
输出:["1","2","Fizz"]

示例 2:

输入:n = 5
输出:["1","2","Fizz","4","Buzz"]

示例 3:

输入:n = 15
输出:["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]

提示:

  • 1 <= n <= 104
class Solution {
public:
	vector<string> fizzBuzz(int n) {
		vector<string>ans;
		for (int i = 1; i <= n; i++) {
			string s = "";
			if (i % 3 && i % 5)s = to_string(i);
			if (i % 3 == 0)s += "Fizz";
			if (i % 5 == 0)s += "Buzz";
			ans.push_back(s);
		}
		return ans;
	}
};

604. 迭代压缩字符串

设计并实现一个迭代压缩字符串的数据结构。给定的压缩字符串的形式是,每个字母后面紧跟一个正整数,表示该字母在原始未压缩字符串中出现的次数。

设计一个数据结构,它支持如下两种操作: next 和 hasNext

  • next() - 如果原始字符串中仍有未压缩字符,则返回下一个字符,否则返回空格
  • hasNext() - 如果原始字符串中存在未压缩的的字母,则返回true,否则返回false

示例 1:

输入:
["StringIterator", "next", "next", "next", "next", "next", "next", "hasNext", "next", "hasNext"]
[["L1e2t1C1o1d1e1"], [], [], [], [], [], [], [], [], []]
输出:
[null, "L", "e", "e", "t", "C", "o", true, "d", true]

解释:
StringIterator stringIterator = new StringIterator("L1e2t1C1o1d1e1");
stringIterator.next(); // 返回 "L"
stringIterator.next(); // 返回 "e"
stringIterator.next(); // 返回 "e"
stringIterator.next(); // 返回 "t"
stringIterator.next(); // 返回 "C"
stringIterator.next(); // 返回 "o"
stringIterator.hasNext(); // 返回 True
stringIterator.next(); // 返回 "d"
stringIterator.hasNext(); // 返回 True

提示:

  • 1 <= compressedString.length <= 1000
  • compressedString 由小写字母、大写字母和数字组成。
  • 在 compressedString 中,单个字符的重复次数在 [1,10 ^9] 范围内。
  • next 和 hasNext 的操作数最多为 100 。
class StringIterator {
public:
    StringIterator(string compressedString) {
        init(compressedString);
    }
    void init(const string &s){
        if(s.empty())return;
        int x=0,len=0;
        for(int i=1;i<=3;i++){
            if(i<s.length()&&s[i]>='0'&&s[i]<='9'){
                x=x*10+(s[i]-'0');
                len=i+1;
            }else break;
        }
        for(int i=0;i<100&&i<x;i++)v.push_back(s[0]);
        if(x<100)init(s.substr(len,s.length()-len));
    }

    
    char next() {
        if(id>=v.size())return ' ';
        id++;
        return v[id-1];
    }
    
    bool hasNext() {
        return id<v.size();
    }
    vector<char>v;
    int id=0;
};

734. 句子相似性

我们可以将一个句子表示为一个单词数组,例如,句子 "I am happy with leetcode" 可以表示为 arr = ["I","am",happy","with","leetcode"]

给定两个句子 sentence1 和 sentence2 分别表示为一个字符串数组,并给定一个字符串对 similarPairs ,其中 similarPairs[i] = [xi, yi] 表示两个单词 xi and yi 是相似的。

如果 sentence1 和 sentence2 相似则返回 true ,如果不相似则返回 false 。

两个句子是相似的,如果:

  • 它们具有 相同的长度 (即相同的字数)
  • sentence1[i] 和 sentence2[i] 是相似的

请注意,一个词总是与它自己相似,也请注意,相似关系是不可传递的。例如,如果单词 a 和 b 是相似的,单词 b 和 c 也是相似的,那么 a 和 c  不一定相似 。

示例 1:

输入: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","fine"],["drama","acting"],["skills","talent"]]
输出: true
解释: 这两个句子长度相同,每个单词都相似。

示例 2:

输入: sentence1 = ["great"], sentence2 = ["great"], similarPairs = []
输出: true
解释: 一个单词和它本身相似。

示例 3:

输入: sentence1 = ["great"], sentence2 = ["doubleplus","good"], similarPairs = [["great","doubleplus"]]
输出: false
解释: 因为它们长度不同,所以返回false。

提示:

  • 1 <= sentence1.length, sentence2.length <= 1000
  • 1 <= sentence1[i].length, sentence2[i].length <= 20
  • sentence1[i] 和 sentence2[i] 只包含大小写英文字母
  • 0 <= similarPairs.length <= 2000
  • similarPairs[i].length == 2
  • 1 <= xi.length, yi.length <= 20
  • 所有对 (xi, yi) 都是 不同 的
class Solution {
public:
    bool areSentencesSimilar(vector<string>& sentence1, vector<string>& sentence2, vector<vector<string>>& similarPairs) {
        map<string,vector<string>>m;
        for(auto v:similarPairs){
            m[v[0]].push_back(v[1]);
            m[v[1]].push_back(v[0]);
        }
        if(sentence1.size()!=sentence2.size())return false;
        for(int i=0;i<sentence1.size();i++){
            bool flag = sentence1[i]==sentence2[i];
            for(auto s:m[sentence1[i]])if(s==sentence2[i])flag=true;
            if(flag==false)return false;
        }
        return true;
    }
};

1065. 字符串的索引对

给出 字符串 text 和 字符串列表 words, 返回所有的索引对 [i, j] 使得在索引对范围内的子字符串 text[i]...text[j](包括 i 和 j)属于字符串列表 words

示例 1:

输入: text = "thestoryofleetcodeandme", words = ["story","fleet","leetcode"]
输出: [[3,7],[9,13],[10,17]]

示例 2:

输入: text = "ababa", words = ["aba","ab"]
输出: [[0,1],[0,2],[2,3],[2,4]]
解释: 
注意,返回的配对可以有交叉,比如,"aba" 既在 [0,2] 中也在 [2,4] 中

提示:

  1. 所有字符串都只包含小写字母。
  2. 保证 words 中的字符串无重复。
  3. 1 <= text.length <= 100
  4. 1 <= words.length <= 20
  5. 1 <= words[i].length <= 50
  6. 按序返回索引对 [i,j](即,按照索引对的第一个索引进行排序,当第一个索引对相同时按照第二个索引对排序)。
class Solution {
public:
    vector<vector<int>> indexPairs(string text, vector<string>& words) {
        vector<vector<int>>ans;
        map<string,int>m;
        for(auto s:words)m[s]++;
        for(int i=0;i<text.length();i++){
            for(int j=i;j<text.length();j++){
                if(m[text.substr(i,j-i+1)])ans.push_back(vector<int>{i,j});
            }
        }
        return ans;
    }
};

1119. 删去字符串中的元音

给你一个字符串 s ,请你删去其中的所有元音字母 'a''e''i''o''u',并返回这个新字符串。

示例 1:

输入:s = "leetcodeisacommunityforcoders"
输出:"ltcdscmmntyfrcdrs"

示例 2:

输入:s = "aeiou"
输出:""

提示:

  • 1 <= S.length <= 1000
  • s 仅由小写英文字母组成
class Solution {
public:
    string removeVowels(string s) {
        string ans;
        for(auto c:s){
            if(c!='a'&&c!='e'&&c!='i'&&c!='o'&&c!='u')ans+=c;
        }
        return ans;
    }
};

1180. 统计只含单一字母的子串

给你一个字符串 s,返回 只含 单一字母 的子串个数 。

示例 1:

输入: s = "aaaba"
输出: 8
解释: 只含单一字母的子串分别是 "aaa", "aa", "a", "b"。
"aaa" 出现 1 次。
"aa" 出现 2 次。
"a" 出现 4 次。
"b" 出现 1 次。
所以答案是 1 + 2 + 4 + 1 = 8。

示例 2:

输入: s = "aaaaaaaaaa"
输出: 55

提示:

  • 1 <= s.length <= 1000
  • s[i] 仅由小写英文字母组成
class Solution {
public:
    int countLetters(string s) {
        char c0='\0';
        int num=0, ans=0;
        for(auto c:s){
            if(c==c0)num++;
            else c0=c,ans+=num*(num+1)/2,num=1;
        }
        return ans+num*(num+1)/2;
    }
};

1662. 检查两个字符串数组是否相等

给你两个字符串数组 word1 和 word2 。如果两个数组表示的字符串相同,返回 true ;否则,返回 false 。

数组表示的字符串 是由数组中的所有元素 按顺序 连接形成的字符串。

示例 1:

输入:word1 = ["ab", "c"], word2 = ["a", "bc"]
输出:true
解释:
word1 表示的字符串为 "ab" + "c" -> "abc"
word2 表示的字符串为 "a" + "bc" -> "abc"
两个字符串相同,返回 true

示例 2:

输入:word1 = ["a", "cb"], word2 = ["ab", "c"]
输出:false

示例 3:

输入:word1  = ["abc", "d", "defg"], word2 = ["abcddefg"]
输出:true

提示:

  • 1 <= word1.length, word2.length <= 103
  • 1 <= word1[i].length, word2[i].length <= 103
  • 1 <= sum(word1[i].length), sum(word2[i].length) <= 103
  • word1[i] 和 word2[i] 由小写字母组成

class Solution {
public:
    bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
        return GetVecSum(word1)==GetVecSum(word2);
    }
};

1684. 统计一致字符串的数目

 给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 

请你返回 words 数组中 一致字符串 的数目。

示例 1:

输入:allowed = "ab", words = ["ad","bd","aaab","baa","badab"]
输出:2
解释:字符串 "aaab" 和 "baa" 都是一致字符串,因为它们只包含字符 'a' 和 'b' 。

示例 2:

输入:allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"]
输出:7
解释:所有字符串都是一致的。

示例 3:

输入:allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"]
输出:4
解释:字符串 "cc","acd","ac" 和 "d" 是一致字符串。

提示:

  • 1 <= words.length <= 104
  • 1 <= allowed.length <= 26
  • 1 <= words[i].length <= 10
  • allowed 中的字符 互不相同 。
  • words[i] 和 allowed 只包含小写英文字母。
class Solution {
public:
    int countConsistentStrings(string allowed, vector<string>& words) {
        map<char,int>m;
        for(auto c:allowed)m[c]=1;
        int ans=0;
        for(auto str:words){
            int flag=1;
            for(auto c:str)if(m[c]==0){
                flag=0;
                break;
            }
            ans+=flag;
        }
        return ans;
    }
};

1704. 判断字符串的两半是否相似

给你一个偶数长度的字符串 s 。将其拆分成长度相同的两半,前一半为 a ,后一半为 b 。

两个字符串 相似 的前提是它们都含有相同数目的元音('a''e''i''o''u''A''E''I''O''U')。注意,s 可能同时含有大写和小写字母。

如果 a  b 相似,返回 true ;否则,返回 false 。

示例 1:

输入:s = "book"
输出:true
解释:a = "bo" 且 b = "ok" 。a 中有 1 个元音,b 也有 1 个元音。所以,a 和 b 相似。

示例 2:

输入:s = "textbook"
输出:false
解释:a = "text" 且 b = "book" 。a 中有 1 个元音,b 中有 2 个元音。因此,a 和 b 不相似。
注意,元音 o 在 b 中出现两次,记为 2 个。

提示:

  • 2 <= s.length <= 1000
  • s.length 是偶数
  • s 由 大写和小写 字母组成
class Solution {
public:
    bool halvesAreAlike(string s) {
        int n=0;
        for(int i=0;i<s.length();i++){
            char c=s[i];
            if(c>='A'&&c<='Z')c=c-'A'+'a';
            if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')n+=(i<s.length()/2?1:-1);
        }
        return !n;
    }
};

1768. 交替合并字符串

给你两个字符串 word1 和 word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。

返回 合并后的字符串 。

示例 1:

输入:word1 = "abc", word2 = "pqr"
输出:"apbqcr"
解释:字符串合并情况如下所示:
word1:  a   b   c
word2:    p   q   r
合并后:  a p b q c r

示例 2:

输入:word1 = "ab", word2 = "pqrs"
输出:"apbqrs"
解释:注意,word2 比 word1 长,"rs" 需要追加到合并后字符串的末尾。
word1:  a   b 
word2:    p   q   r   s
合并后:  a p b q   r   s

示例 3:

输入:word1 = "abcd", word2 = "pq"
输出:"apbqcd"
解释:注意,word1 比 word2 长,"cd" 需要追加到合并后字符串的末尾。
word1:  a   b   c   d
word2:    p   q 
合并后:  a p b q c   d

提示:

  • 1 <= word1.length, word2.length <= 100
  • word1 和 word2 由小写英文字母组成
class Solution {
public:
	string mergeAlternately(string word1, string word2) {
		string ans(word1.length()+ word2.length(),'0');
		for (int i = 0; i < word1.length() && i < word2.length(); i++)ans[i * 2] = word1[i], ans[i * 2 + 1] = word2[i];
		for (int i = word2.length(); i < word1.length(); i++)ans[word2.length() + i] = word1[i];
		for (int i = word1.length(); i < word2.length(); i++)ans[word1.length() + i] = word2[i];
		return ans;
	}
};

1796. 字符串中第二大的数字

给你一个混合字符串 s ,请你返回 s 中 第二大 的数字,如果不存在第二大的数字,请你返回 -1 。

混合字符串 由小写英文字母和数字组成。

示例 1:

输入:s = "dfa12321afd"
输出:2
解释:出现在 s 中的数字包括 [1, 2, 3] 。第二大的数字是 2 。

示例 2:

输入:s = "abc1111"
输出:-1
解释:出现在 s 中的数字只包含 [1] 。没有第二大的数字。

提示:

  • 1 <= s.length <= 500
  • s 只包含小写英文字母和(或)数字。
class Solution {
public:
	int secondHighest(string s) {
		map<int, int>m;
		for (auto c : s)if(c>='0'&&c<='9')m[c-'0'];
		if (m.size() < 2)return -1;
		auto it = m.end();
		it--, it--;
		return it->first;
	}
};

1805. 字符串中不同整数的数目

给你一个字符串 word ,该字符串由数字和小写英文字母组成。

请你用空格替换每个不是数字的字符。例如,"a123bc34d8ef34" 将会变成 " 123  34 8  34" 。注意,剩下的这些整数为(相邻彼此至少有一个空格隔开):"123""34""8" 和 "34" 。

返回对 word 完成替换后形成的 不同 整数的数目。

只有当两个整数的 不含前导零 的十进制表示不同, 才认为这两个整数也不同。

示例 1:

输入:word = "a123bc34d8ef34"
输出:3
解释:不同的整数有 "123"、"34" 和 "8" 。注意,"34" 只计数一次。

示例 2:

输入:word = "leet1234code234"
输出:2

示例 3:

输入:word = "a1b01c001"
输出:1
解释:"1"、"01" 和 "001" 视为同一个整数的十进制表示,因为在比较十进制值时会忽略前导零的存在。

提示:

  • 1 <= word.length <= 1000
  • word 由数字和小写英文字母组成
class Solution {
public:
	int numDifferentIntegers(string word) {
		map<char, int>splitChar;
		for (char c = 'a'; c <= 'z'; c++)splitChar[c] = 1;
		vector<string> v = StringSplit(word, splitChar);
		map<string, int>m;
		for (auto s : v) {
			int id = 0;
			while (id < s.length() - 1 && s[id] == '0')id++;
			m[s.substr(id, s.length() - id)];
		}
		return m.size();
	}
};

1807. 替换字符串中的括号内容

给你一个字符串 s ,它包含一些括号对,每个括号中包含一个 非空 的键。

比方说,字符串 "(name)is(age)yearsold" 中,有 两个 括号对,分别包含键 "name" 和 "age" 。
你知道许多键对应的值,这些关系由二维字符串数组 knowledge 表示,其中 knowledge[i] = [keyi, valuei] ,表示键 keyi 对应的值为 valuei 。

你需要替换 所有 的括号对。当你替换一个括号对,且它包含的键为 keyi 时,你需要:

将 keyi 和括号用对应的值 valuei 替换。
如果从 knowledge 中无法得知某个键对应的值,你需要将 keyi 和括号用问号 "?" 替换(不需要引号)。
knowledge 中每个键最多只会出现一次。s 中不会有嵌套的括号。

请你返回替换 所有 括号对后的结果字符串。

示例 1:

输入:s = "(name)is(age)yearsold", knowledge = [["name","bob"],["age","two"]]
输出:"bobistwoyearsold"
解释:
键 "name" 对应的值为 "bob" ,所以将 "(name)" 替换为 "bob" 。
键 "age" 对应的值为 "two" ,所以将 "(age)" 替换为 "two" 。
示例 2:

输入:s = "hi(name)", knowledge = [["a","b"]]
输出:"hi?"
解释:由于不知道键 "name" 对应的值,所以用 "?" 替换 "(name)" 。
示例 3:

输入:s = "(a)(a)(a)aaa", knowledge = [["a","yes"]]
输出:"yesyesyesaaa"
解释:相同的键在 s 中可能会出现多次。
键 "a" 对应的值为 "yes" ,所以将所有的 "(a)" 替换为 "yes" 。
注意,不在括号里的 "a" 不需要被替换。
 

提示:

1 <= s.length <= 105
0 <= knowledge.length <= 105
knowledge[i].length == 2
1 <= keyi.length, valuei.length <= 10
s 只包含小写英文字母和圆括号 '(' 和 ')' 。
s 中每一个左圆括号 '(' 都有对应的右圆括号 ')' 。
s 中每对括号内的键都不会为空。
s 中不会有嵌套括号对。
keyi 和 valuei 只包含小写英文字母。
knowledge 中的 keyi 不会重复。

class Solution {
public:
	string evaluate(string s, vector<vector<string>>& knowledge) {
		for (auto vi : knowledge)m[vi[0]] = vi[1];
		vector<string> v = stringSplit(s);
		string ans;
		for (auto vi : v)ans += vi;
		return ans;
	}
	vector<string> stringSplit(string text)
	{
		vector<string>v;
		v.clear();
		int low = 0, key = 0;
		for (int i = 0; i <= text.length(); i++)
		{
			if (i == text.length() || text[i] == '(')
			{
				if (i > low)v.push_back(text.substr(low, i - low));
				low = i + 1;
			}
			else if (text[i] == ')')
			{
				if (i > low) {
					auto s = text.substr(low, i - low);
					v.push_back(m[s]==""?"?":m[s]);
				}
				low = i + 1;
			}
		}
		return v;
	}
	map<string, string>m;
};

1813. 句子相似性 III

一个句子是由一些单词与它们之间的单个空格组成,且句子的开头和结尾没有多余空格。比方说,"Hello World" ,"HELLO" ,"hello world hello world" 都是句子。每个单词都 只 包含大写和小写英文字母。

如果两个句子 sentence1 和 sentence2 ,可以通过往其中一个句子插入一个任意的句子(可以是空句子)而得到另一个句子,那么我们称这两个句子是 相似的 。比方说,sentence1 = "Hello my name is Jane" 且 sentence2 = "Hello Jane" ,我们可以往 sentence2 中 "Hello" 和 "Jane" 之间插入 "my name is" 得到 sentence1 。

给你两个句子 sentence1 和 sentence2 ,如果 sentence1 和 sentence2 是相似的,请你返回 true ,否则返回 false 。

示例 1:

输入:sentence1 = "My name is Haley", sentence2 = "My Haley"
输出:true
解释:可以往 sentence2 中 "My" 和 "Haley" 之间插入 "name is" ,得到 sentence1 。
示例 2:

输入:sentence1 = "of", sentence2 = "A lot of words"
输出:false
解释:没法往这两个句子中的一个句子只插入一个句子就得到另一个句子。
示例 3:

输入:sentence1 = "Eating right now", sentence2 = "Eating"
输出:true
解释:可以往 sentence2 的结尾插入 "right now" 得到 sentence1 。
示例 4:

输入:sentence1 = "Luky", sentence2 = "Lucccky"
输出:false
 

提示:

1 <= sentence1.length, sentence2.length <= 100
sentence1 和 sentence2 都只包含大小写英文字母和空格。
sentence1 和 sentence2 中的单词都只由单个空格隔开。

class Solution {
public:
	bool areSentencesSimilar(string s1, string s2) {
		auto v1 = StringSplit(s1, ' ');
		auto v2 = StringSplit(s2, ' ');
		if (v1.size() > v2.size()) {
			auto v3 = v2;
			v2 = v1, v1 = v3;
		}
		int n = v1.size();
		for (int i = 0; i < v1.size(); i++) {
			if (v1[i] != v2[i])break;
			if (--n == 0)return true;
		}
		for (int i = 0; i < v1.size(); i++) {
			if (v1[v1.size()-1-i] != v2[v2.size() -1- i])break;
			if (--n == 0)return true;
		}
		return false;
	}
};

1814. 统计一个数组中好对子的数目

给你一个数组 nums ,数组中只包含非负整数。定义 rev(x) 的值为将整数 x 各个数字位反转得到的结果。比方说 rev(123) = 321 , rev(120) = 21 。我们称满足下面条件的下标对 (i, j) 是 好的 :

0 <= i < j < nums.length
nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
请你返回好下标对的数目。由于结果可能会很大,请将结果对 109 + 7 取余 后返回。

示例 1:

输入:nums = [42,11,1,97]
输出:2
解释:两个坐标对为:
 - (0,3):42 + rev(97) = 42 + 79 = 121, 97 + rev(42) = 97 + 24 = 121 。
 - (1,2):11 + rev(1) = 11 + 1 = 12, 1 + rev(11) = 1 + 11 = 12 。
示例 2:

输入:nums = [13,10,35,24,76]
输出:4
 

提示:

1 <= nums.length <= 105
0 <= nums[i] <= 109

class Solution {
public:
	int countNicePairs(vector<int>& nums) {
		map<int, int>m;
		int ans = 0;
		for (auto n : nums)ans=(ans+m[n - rev(n)]++)%1000000007;
		return ans;
	}
	int rev(int x)
	{
		char* ch;
		IntToStr(x, 10, ch);
		auto v = Frev(StringToCharVec(CharToString(ch)));
		auto ans= StrToInt(v.data(),v.size(),10);
		return ans;
	}
};

2042. 检查句子中的数字是否递增

句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个由小写英文字母组成的 单词 。

示例,"a puppy has 2 eyes 4 legs" 是一个由 7 个 token 组成的句子:"2" 和 "4" 是数字,其他像 "puppy" 这样的 tokens 属于单词。
给你一个表示句子的字符串 s ,你需要检查 s 中的 全部 数字是否从左到右严格递增(即,除了最后一个数字,s 中的 每个 数字都严格小于它 右侧 的数字)。

如果满足题目要求,返回 true ,否则,返回 false 。

示例 1:

输入:s = "1 box has 3 blue 4 red 6 green and 12 yellow marbles"
输出:true
解释:句子中的数字是:1, 3, 4, 6, 12 。
这些数字是按从左到右严格递增的 1 < 3 < 4 < 6 < 12 。
示例 2:

输入:s = "hello world 5 x 5"
输出:false
解释:句子中的数字是:5, 5 。这些数字不是严格递增的。
示例 3:

输入:s = "sunset is at 7 51 pm overnight lows will be in the low 50 and 60 s"
输出:false
解释:s 中的数字是:7, 51, 50, 60 。这些数字不是严格递增的。
示例 4:

输入:s = "4 5 11 26"
输出:true
解释:s 中的数字是:4, 5, 11, 26 。
这些数字是按从左到右严格递增的:4 < 5 < 11 < 26 。
 

提示:

3 <= s.length <= 200
s 由小写英文字母、空格和数字 0 到 9 组成(包含 0 和 9)
s 中数字 token 的数目在 2 和 100 之间(包含 2 和 100)
s 中的 token 之间由单个空格分隔
s 中至少有 两个 数字
s 中的每个数字都是一个 小于 100 的 正 数,且不含前导零
s 不含前导或尾随空格

class Solution {
public:
	bool areNumbersAscending(string s) {
		vector<string> v = StringSplit(s, ' ');
		int pre = 0;
		for (auto vi : v) {
			if (vi[0] >= '0'&&vi[0] <= '9') {
				int x = StrToInt(StringToChar(vi), 10);
				if (x <= pre)return false;
				pre = x;
			}
		}
		return true;
	}
};

2185. 统计包含给定前缀的字符串

给你一个字符串数组 words 和一个字符串 pref 。

返回 words 中以 pref 作为 前缀 的字符串的数目。

字符串 s 的 前缀 就是  s 的任一前导连续字符串。

示例 1:

输入:words = ["pay","attention","practice","attend"], pref = "at"
输出:2
解释:以 "at" 作为前缀的字符串有两个,分别是:"attention" 和 "attend" 。
示例 2:

输入:words = ["leetcode","win","loops","success"], pref = "code"
输出:0
解释:不存在以 "code" 作为前缀的字符串。
 

提示:

1 <= words.length <= 100
1 <= words[i].length, pref.length <= 100
words[i] 和 pref 由小写英文字母组成

class Solution {
public:
    int prefixCount(vector<string>& words, string pref) {
        int ans=0;
        for(auto w:words){
            ans+=(w.length()>=pref.length() && w.substr(0,pref.length())==pref);
        }
        return ans;
    }
};

2283. 判断一个数的数字计数是否等于数位的值

给你一个下标从 0 开始长度为 n 的字符串 num ,它只包含数字。

如果对于 每个 0 <= i < n 的下标 i ,都满足数位 i 在 num 中出现了 num[i]次,那么请你返回 true ,否则返回 false 。

示例 1:

输入:num = "1210"
输出:true
解释:
num[0] = '1' 。数字 0 在 num 中出现了一次。
num[1] = '2' 。数字 1 在 num 中出现了两次。
num[2] = '1' 。数字 2 在 num 中出现了一次。
num[3] = '0' 。数字 3 在 num 中出现了零次。
"1210" 满足题目要求条件,所以返回 true 。
示例 2:

输入:num = "030"
输出:false
解释:
num[0] = '0' 。数字 0 应该出现 0 次,但是在 num 中出现了一次。
num[1] = '3' 。数字 1 应该出现 3 次,但是在 num 中出现了零次。
num[2] = '0' 。数字 2 在 num 中出现了 0 次。
下标 0 和 1 都违反了题目要求,所以返回 false 。
 

提示:

n == num.length
1 <= n <= 10
num 只包含数字。

class Solution {
public:
    bool digitCount(string num) {
        map<int,int>m;
        for(auto c:num)m[c-'0']++;
        for(int i=0;i<num.size();i++)if(m[i]!=num[i]-'0')return false;
        return true;
    }
};

2287. 重排字符形成目标字符串

给你两个下标从 0 开始的字符串 s 和 target 。你可以从 s 取出一些字符并将其重排,得到若干新的字符串。

从 s 中取出字符并重新排列,返回可以形成 target 的 最大 副本数。

示例 1:

输入:s = "ilovecodingonleetcode", target = "code"
输出:2
解释:
对于 "code" 的第 1 个副本,选取下标为 4 、5 、6 和 7 的字符。
对于 "code" 的第 2 个副本,选取下标为 17 、18 、19 和 20 的字符。
形成的字符串分别是 "ecod" 和 "code" ,都可以重排为 "code" 。
可以形成最多 2 个 "code" 的副本,所以返回 2 。
示例 2:

输入:s = "abcba", target = "abc"
输出:1
解释:
选取下标为 0 、1 和 2 的字符,可以形成 "abc" 的 1 个副本。 
可以形成最多 1 个 "abc" 的副本,所以返回 1 。
注意,尽管下标 3 和 4 分别有额外的 'a' 和 'b' ,但不能重用下标 2 处的 'c' ,所以无法形成 "abc" 的第 2 个副本。
示例 3:

输入:s = "abbaccaddaeea", target = "aaaaa"
输出:1
解释:
选取下标为 0 、3 、6 、9 和 12 的字符,可以形成 "aaaaa" 的 1 个副本。
可以形成最多 1 个 "aaaaa" 的副本,所以返回 1 。
 

提示:

1 <= s.length <= 100
1 <= target.length <= 10
s 和 target 由小写英文字母组成

class Solution {
public:
	int rearrangeCharacters(string s1, string s2) {
		map<char, int>m1, m2;
		for (auto c : s1)m1[c]++;
		for (auto c : s2)m2[c]++;
		int ans = INT_MAX;
		for (auto p : m2)ans = min(ans, m1[p.first] / p.second);
		return ans;
	}
};

2299. 强密码检验器 II

如果一个密码满足以下所有条件,我们称它是一个 强 密码:

它有至少 8 个字符。
至少包含 一个小写英文 字母。
至少包含 一个大写英文 字母。
至少包含 一个数字 。
至少包含 一个特殊字符 。特殊字符为:"!@#$%^&*()-+" 中的一个。
它 不 包含 2 个连续相同的字符(比方说 "aab" 不符合该条件,但是 "aba" 符合该条件)。
给你一个字符串 password ,如果它是一个 强 密码,返回 true,否则返回 false 。

示例 1:

输入:password = "IloveLe3tcode!"
输出:true
解释:密码满足所有的要求,所以我们返回 true 。
示例 2:

输入:password = "Me+You--IsMyDream"
输出:false
解释:密码不包含数字,且包含 2 个连续相同的字符。所以我们返回 false 。
示例 3:

输入:password = "1aB!"
输出:false
解释:密码不符合长度要求。所以我们返回 false 。
 

提示:

1 <= password.length <= 100
password 包含字母,数字和 "!@#$%^&*()-+" 这些特殊字符。

class Solution {
public:
    bool strongPasswordCheckerII(string s) {
        if(s.length()<8)return false;
        bool low=false,up=false,num=false,sp=false;
        string str="!@#$%^&*()-+";
        for(int i=0;i<s.length();i++){
            if(i&&s[i]==s[i-1])return false;
            if(islower(s[i]))low=true;
            if(isupper(s[i]))up=true;
            if(isdigit(s[i]))num=true;
            if(find(str.begin(),str.end(),s[i])!=str.end())sp=true;
        }
        return low&&up&&num&&sp;
    }
};

2309. 兼具大小写的最好英文字母

给你一个由英文字母组成的字符串 s ,请你找出并返回 s 中的 最好 英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母,则返回一个空字符串。

最好 英文字母的大写和小写形式必须 都 在 s 中出现。

英文字母 b 比另一个英文字母 a 更好 的前提是:英文字母表中,b 在 a 之 后 出现。

示例 1:

输入:s = "lEeTcOdE"
输出:"E"
解释:
字母 'E' 是唯一一个大写和小写形式都出现的字母。
示例 2:

输入:s = "arRAzFif"
输出:"R"
解释:
字母 'R' 是大写和小写形式都出现的最好英文字母。
注意 'A' 和 'F' 的大写和小写形式也都出现了,但是 'R' 比 'F' 和 'A' 更好。
示例 3:

输入:s = "AbCdEfGhIjK"
输出:""
解释:
不存在大写和小写形式都出现的字母。
 

提示:

1 <= s.length <= 1000
s 由小写和大写英文字母组成

class Solution {
public:
    string greatestLetter(string s) {
        map<char,int>m;
        for(auto c:s)m[c]=1;
        s="";
        for(char c='Z';c>='A';c--)if(m[c]&&m[c+32])return s+c;
        return s;
    }
};

2496. 数组中字符串的最大值

一个由字母和数字组成的字符串的 值 定义如下:

如果字符串 只 包含数字,那么值为该字符串在 10 进制下的所表示的数字。
否则,值为字符串的 长度 。
给你一个字符串数组 strs ,每个字符串都只由字母和数字组成,请你返回 strs 中字符串的 最大值 。

示例 1:

输入:strs = ["alic3","bob","3","4","00000"]
输出:5
解释:
- "alic3" 包含字母和数字,所以值为长度 5 。
- "bob" 只包含字母,所以值为长度 3 。
- "3" 只包含数字,所以值为 3 。
- "4" 只包含数字,所以值为 4 。
- "00000" 只包含数字,所以值为 0 。
所以最大的值为 5 ,是字符串 "alic3" 的值。
示例 2:

输入:strs = ["1","01","001","0001"]
输出:1
解释:
数组中所有字符串的值都是 1 ,所以我们返回 1 。
 

提示:

1 <= strs.length <= 100
1 <= strs[i].length <= 9
strs[i] 只包含小写英文字母和数字。

class Solution {
public:
    int maximumValue(vector<string>& strs) {
        int ans=0;
        for(auto s:strs){
            bool flag=false;
            for(auto c:s)if(c<'0'||c>'9')flag=true;
            ans=max(ans,flag?int(s.length()):int(StrToInt(s.data(), 10)));
        }
        return ans;
    }
};

2710. 移除字符串中的尾随零

给你一个用字符串表示的正整数 num ,请你以字符串形式返回不含尾随零的整数 num 

示例 1:

输入:num = "51230100"
输出:"512301"
解释:整数 "51230100" 有 2 个尾随零,移除并返回整数 "512301" 。

示例 2:

输入:num = "123"
输出:"123"
解释:整数 "123" 不含尾随零,返回整数 "123" 。

提示:

  • 1 <= num.length <= 1000
  • num 仅由数字 0 到 9 组成
  • num 不含前导零
class Solution {
public:
	string removeTrailingZeros(string num) {
		if (num[num.length() - 1] != '0')return num;
		for (int i = num.length() - 1; i >= 0; i--) {
			if (num[i] != '0')return num.substr(0, i + 1);
		}
		return num;
	}
};

2828. 判别首字母缩略词

给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。

如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s ,则认为 s 是 words 的首字母缩略词。例如,"ab" 可以由 ["apple", "banana"] 形成,但是无法从 ["bear", "aardvark"] 形成。

如果 s 是 words 的首字母缩略词,返回 true ;否则,返回 false 。

示例 1:

输入:words = ["alice","bob","charlie"], s = "abc"
输出:true
解释:words 中 "alice"、"bob" 和 "charlie" 的第一个字符分别是 'a'、'b' 和 'c'。因此,s = "abc" 是首字母缩略词。 

示例 2:

输入:words = ["an","apple"], s = "a"
输出:false
解释:words 中 "an" 和 "apple" 的第一个字符分别是 'a' 和 'a'。
串联这些字符形成的首字母缩略词是 "aa" 。
因此,s = "a" 不是首字母缩略词。

示例 3:

输入:words = ["never","gonna","give","up","on","you"], s = "ngguoy"
输出:true
解释:串联数组 words 中每个字符串的第一个字符,得到字符串 "ngguoy" 。
因此,s = "ngguoy" 是首字母缩略词。 

提示:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 10
  • 1 <= s.length <= 100
  • words[i] 和 s 由小写英文字母组成
class Solution {
public:
    bool isAcronym(vector<string>& words, string s) {
        if(words.size()!=s.length())return false;
        for(int i=0;i<words.size();i++){
            if(words[i][0]!=s[i])return false;
        }
        return true;
    }
};

2864. 最大二进制奇数

给你一个 二进制 字符串 s ,其中至少包含一个 '1' 。

你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。

以字符串形式,表示并返回可以由给定组合生成的最大二进制奇数。

注意 返回的结果字符串 可以 含前导零。

示例 1:

输入:s = "010"
输出:"001"
解释:因为字符串 s 中仅有一个 '1' ,其必须出现在最后一位上。所以答案是 "001" 。

示例 2:

输入:s = "0101"
输出:"1001"
解释:其中一个 '1' 必须出现在最后一位上。而由剩下的数字可以生产的最大数字是 "100" 。所以答案是 "1001" 。

提示:

  • 1 <= s.length <= 100
  • s 仅由 '0' 和 '1' 组成
  • s 中至少包含一个 '1'
class Solution {
public:
    string maximumOddBinaryNumber(string s) {
        int n0=0,n1=-1;
        for(auto c:s){
            if(c=='0')n0++;
            else n1++;
        }
        string ans;
        while(n1--)ans+='1';
        while(n0--)ans+='0';
        return ans+'1';
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值