最長の回文部分文字列
タイトルの説明
文字列sを指定して、sで最も長い回文部分文字列を見つけます。sの最大長は1000と想定できます。
問題解決のアイデア
このウィンドウの右ボーダーが右に移動し、左ボーダーが右ボーダーの下付き文字から左に移動することを除いて、重複することなく最長のサブストリングのようなスライディングウィンドウを使用できます。
また、現在のウィンドウに記録されている文字列が回文かどうかを記録するための2次元配列と、回文
の長さを記録する変数が必要です。最大の回文列を比較する
例:baccab
- 最初に右境界右、左境界左=右を定義します。右境界の下付き文字から始めて、現在のウィンドウが回文かどうかを判断する方法は?最初のステップ:両端が等しい
str[i] == str[j]
かどうかの判断、2番目のステップ:両端以外のウィンドウ内の文字列が回文かどうかの判断:s[i+1][j-1]
、長さが3左右<= 2未満で、両端が同じ場合、両端は回文である必要があります。上記の判断の後、現在の間隔は回文列であると説明できるため、i〜j間隔をマークしarray[i][j] = true;
て回文列を記録し、長さを計算します。間隔の長さが以前に記録された回文列の長さより大きい場合は、right-left> lengthを記録します。res = susbtr(left、right-left + 1);左右の+1の長さは、左の境界から遮断されます。長さ=右から左。 - baccabの場合、最初のstr [右] = b、str [左] = str [右] = b、両端は同じで、長さが3未満であるため、bは回文列であり、
array[i][j] =true;
長さは長さレコードよりも長い - すると、右がaの位置になり、左もaの位置になり、左に行き始め、bに行き、両端が違うと判断して、直接次のループに行く
- 右が再びcの位置になります。
コードの実装
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
//记录字符串是否为回文字符串
vector<vector<bool>> array (n,vector<bool>(n));
string res = "";//记录结果返回
int length = 0; //记录长度,比较出最长的回文子串
if(n == 0)
return s;
if(n == 1)
return s;
//如果是两个字符,则返回第一个字符
res = s[0];
//外层循环右边界
for(int right = 0;right<n;++right)
{
//内层循环左边界
for(int left = right;left>=0;--left)
{
//判断是否为回文字串
if(s[left] == s[right] //两头相等
&& (right-left<=2 //长度小于等于3,并且两头相等比为回文串
|| array[left+1][right-1]) //去掉两头,中间也是回文串才是回文串
)
{
//标记left~right该区间为回文串
array[left][right] = true;
if(right-left>length) //如果回文串长度大于之前记录的长度,则记录该串
{
res = s.substr(left,right-left+1);
length = right-left; //记录新长度
}
}
}
}
return res;
}
};
ジグザグ変換
タイトルの説明
指定された文字列を、指定された行数に従って、上から下、左から右へジグザグパターンに配置します。
たとえば、入力文字列が "LEETCODEISHIRING"で、行数が3の場合、配置は次のようになります。
問題解決のアイデア
法則を見つけるための合計4行の数値= 4 、
- 行0、0-6-12、間隔6
- 1行目、1-5-7-11-13、間隔は4-2-4-2奇数行
step-2*1(行)-2*1(行)-step-2*1(行)-2*1(行)
- 行2、2-4-8-10-14、間隔は2-4-2-4偶数行
step-2*2(行)-2*2(行)-step-2*2(行)-2*2(行)
- 行3、3-9-15、間隔6
最初の行と最後の行、step = 2*numbers-2
真ん中は中間層の下付き文字の間隔が常にstep-2*行数,2*行数
交互になっています
コードの実装
class Solution {
public:
string convert(string s, int numRows) {
if(numRows == 1) //如果只有一行数据直接返回
return s;
int step = numRows*2 - 2;
string res = "";
int index = 0; //记录每行元素的下标
int add = 0; //中间行间隔
for(int i = 0; i<numRows;++i)
{
index = i; //标记行数
add = 2*i ; //出去第0行和numRows-1行中间行的间隔
while(index<s.size()) //元素下标大于总个数要换行
{
res+=s[index];
add = step - add ; //变换间隔,
index += (i == 0 || i == numRows-1) ? step : add; //每行每个元素的下标都在变
}
}
return res;
}
};