5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
此问题可拆分为子问题进行求解,且子问题的解包含在问题的解中,因此可采用动态规划。
思路:
回文字符串特征:首字符与尾字符相同,最长回文字符串被去除首尾字符之后仍然是回文字符串,因此自底向上只需考虑首字符是否与尾字符相同。
字符串长度为1时,为回文字符串。
字符串长度为2或3时,若首尾字符串相同,则为回文字符串。
用
s
[
i
:
j
]
s[i:j]
s[i:j]表示回文字符串,则
s
[
i
+
1
:
j
−
1
]
s[i+1:j-1]
s[i+1:j−1]也一定是回文字符串.
动态规划方程(写给自己看的。。。不规范):
s
[
i
:
j
]
=
s
[
i
+
1
:
j
−
1
]
(
回文字符串长度大于
3
)
s[i:j] = s[i+1:j-1] (回文字符串长度大于3)
s[i:j]=s[i+1:j−1](回文字符串长度大于3)
代码:
class Solution {
public:
string longestPalindrome(string s) {
//动态规划
int length = s.length();//字符串长度
if(length==1){
return s;
}
int result_set[length][length];//结果集,result_set[i][j]表示字符串第i个位置到第j个位置间的子串是否为回文字符串。0为否,1为是。
//初始化结果集,当字符串长度为1时,单个字符均为回文子串
for(int i=0; i < length; i++){
result_set[i][i] = 1;
}
//此时
int max_len = 1;//最长回文子串长度为1
int begin_id = 0;//最长回文子串首字母位置可以为任意一个字符的下标,选0
//字符串长度大于1时
for(int l=2; l <= length; l++){
for(int i=0; i < length; i++){
int j = l + i - 1;//j为尾字符位置,因为l=j-i+1,回文字符串的特性->首字符与尾字符相同,字符长度大于1时,比对首字符与尾字符即可
if(j >= length){
break;
}
if(s[i]==s[j]){
if(j-i < 3){
result_set[i][j] = 1;
} else {
result_set[i][j] = result_set[i+1][j-1];
}
//cout << i << " " << j << " " << result_set[i][j] << endl;
if(max_len < l && result_set[i][j] == 1){
max_len = l;
begin_id = i;
}
} else {
result_set[i][j] = 0;
}
}
}
//cout << result_set[1][2] << endl;
//cout << begin_id << " ";
//cout << max_len;
return s.substr(begin_id, max_len);
}
};
6. Z 字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
以Z字形排列,第一行第一个字符与第二个字符之间的间隔为 2 ( n u m R o w s − 1 ) 2(numRows-1) 2(numRows−1)即排列的周期为2(numRows-1),最后一行处于排列周期的分界线处,到达最后一行的字符之前,排列是从上往下的,而到达最后一行的字符后,排列从下往上。
代码:
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1){
return s;
}
string res_set[numRows];//存放排列结果
int rId = 0;
for(int i=0; i < s.length(); i++){
res_set[rId] += s[i];
if(i%(2*numRows-2) < numRows-1 ){//判断是否到达最后一行
rId++;//从上往下排
} else {
--rId;//从下往上排
}
}
string result = "";//拼接字符串数组获取最终结果
for(int i=0; i<numRows; i++){
result += res_set[i];
}
return result;
}
};
string的字符串截取函数s.substr()
string.substr(size_type _Off = 0,size_type _Count = npos);
//size_type _Off表示从哪一个位置开始
//size_type _Count表示截取的字符串长度
string s = "12345";
s.substr(1,3);//从下标1开始,截取长度为3的字符串,即“234”