节选了字符串部分的一些有共性和特性的一些题目
5.最长回文字符串
给你一个字符串 s,找到 s 中最长的回文子串。
示例1:
输入:s = “babad”
输出:”bab”
解释:”aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:”bb”
示例 3:
输入:s = “a”
输出:”a”
示例 4:
输入:s = “ac”
输出:”a”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
法一:中心扩散法
class Solution {
public:
vector maxlength(string s, int start, int end){
int n = s.size() ;
vector ans(2) ;
while(start>= 0 && end ji(2) ; vector ou(2) ; vector result(2) ;
int n = s.size() ;
if(n == 1) return s ;
int max =0 ;
for(int i = 0 ;iou[1] ? ji[1]:ou[1] ;
if(length>max){
max = length ;
result = ji[1]>ou[1] ? ji:ou ;
}
}
return s.substr (result[0], result[1]) ;
}
};
法二:动态规划法
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if (n < 2) {
return s;
}
int maxLen = 1;
int begin = 0;
// dp[i][j] 表示 s[i..j] 是否是回文串
vector> dp(n, vector(n));
// 初始化:所有长度为 1 的子串都是回文串
for (int i = 0; i < n; i++) {
dp[i][i] = true;
}
// 递推开始
// 先枚举子串长度
for (int L = 2; L <= n; L++) {
// 枚举左边界,左边界的上限设置可以宽松一些
for (int i = 0; i < n; i++) {
// 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
int j = L + i - 1;
// 如果右边界越界,就可以退出当前循环
if (j >= n) {
break;
}
if (s[i] != s[j]) {
dp[i][j] = false;
} else {
if (j - i < 3) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
}
// 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
if (dp[i][j] && j - i + 1 > maxLen) {
maxLen = j - i + 1;
begin = i;
}
}
}
return s.substr(begin, maxLen);
}
};
516.最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
输入:s = “bbbab”
输出:4
解释:一个可能的最长回文子序列为 “bbbb” 。
示例 2:
输入:s = “cbbd”
输出:2
解释:一个可能的最长回文子序列为 “bb” 。
提示:
1 <= s.length <= 1000
s
仅由小写英文字母组成
法一:动态规划法
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size() ;
vector> dp(n,vector(n,0)); //初始化二维的容器
for(int i = 0;i=0;i--){
if(s[i] == s[j])
dp[i][j] = dp[i+1][j-1] +2 ;
else
dp[i][j] = max(dp[i+1][j],dp[i][j-1]) ;
}
}
return dp[0][n-1] ;
}
};
541.反转字符串II
给定一个字符串 s 和一个整数 k,从字符串开头算起,每 2k 个字符反转前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = “abcdefg”, k = 2
输出:”bacdfeg”
示例 2:
输入:s = “abcd”, k = 2
输出:”bacd”
提示:
1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.size() ;
for(int i = 0;i
763.划分字母区间
字符串 S
由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = “ababcbacadefegdehijhklij”
输出:[9,7,8]
解释:
划分结果为 “ababcbaca”, “defegde”, “hijhklij”。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。
提示:
S
的长度在[1, 500]
之间。S
只包含小写字母'a'
到'z'
。
class Solution {
public:
vector partitionLabels(string s) {
vectorans,ends(26,-1) ; //这一步是申请两个vector,一个是用来return,一个是用来反映元素最后出现的位置信号
for(int i = 0;i
680.验证回文字符串II
给定一个非空字符串 s
,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: s = “aba”
输出: true
示例 2:
输入: s = “abca”
输出: true
解释: 你可以删除c字符。
示例 3:
输入: s = “abc”
输出: false
提示:
1 <= s.length <= 105
s
由小写英文字母组成
class Solution {
public:
bool validPalindrome(string s) {
if(s.length() <= 2)
return true ;
else{
int left = 0 ;
int right = s.length()-1 ;
while(left
49.字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母都恰好只用一次。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,”tan”],[“ate”,”eat”,”tea”]]
示例 2:
输入: strs = [“”]
输出: [[“”]]
示例 3:
输入: strs = [“a”]
输出: [[“a”]]
提示:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i]
仅包含小写字母
class Solution {
public:
vector> groupAnagrams(vector& strs) {
int num[26] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101} ;
unordered_map> mp ;
vector> result ;
for(string s : strs){
unsigned long long key = 1 ;
for(char c: s){
key *= num[c-'a'] ;
}
mp[key].push_back(s) ;
}
for(auto p : mp){
result.push_back(p.second) ;
}
return result ;
}
};
524.通过删除字母匹配到字典里最长单词
给你一个字符串 s 和一个字符串数组 dictionary 作为字典,找出并返回字典中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。
如果答案不止一个,返回长度最长且字典序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入:s = “abpcplea”, dictionary = [“ale”,”apple”,”monkey”,”plea”]
输出:”apple”
示例 2:
输入:s = “abpcplea”, dictionary = [“a”,”b”,”c”]
输出:”a”
提示:
1 <= s.length <= 1000
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 1000
s 和 dictionary[i] 仅由小写英文字母组成
class Solution {
public:
string findLongestWord(string s, vector& dictionary) {
sort(dictionary.begin(),dictionary.end(),[](string a,string b){
if(a.length() == b.length())
return ab.length() ;
}) ;
for(string str:dictionary){
int i = 0 ;
for(char c: s){
if(i