学習目標:
私はあなたに異なる思考の拡張をもたらすことを望んで、私のユニークなアルゴリズムのアイデアを更新し続けます!
役に立ったら、いいね、フォロー、サポートしてください!
あなたの励ましは私を動かし続けるものです!
!!!
歴口質問銀行質問6公式リンク
学習コンテンツ:
ジグザグ変換
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
例1:
入力:s = "PAYPALISHIRING"、numRows = 3
出力: "PAHNAPLSIIGYIR"
例2:
入力:s = "PAYPALISHIRING"、numRows = 4
出力: "PINALSIGYAHRPI"
説明:
PIN
ALSIG
YAHR
PI
例3:
入力:s = "A"、numRows = 1
出力: "A"
提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、',' 和 '.' 组成
1 <= numRows <= 1000
出典:LeetCode
リンク:https ://leetcode-cn.com/problems/zigzag-conversion
勉強の時間:
2022.1.10
学習出力:
考え1
実行に時間がかかるのはなぜですか?
アルゴリズムロジックは十分に巧妙ではないため、それはハードソリューションの結果です。しかし、デザインのアイデアは非常に賢いです!
問題解決のアイデア
1.まず、2次元配列を使用してZ文字シーケンスを格納し、次に2次元配列を読み取って結果を取得します
。2。この2次元配列をどのように構築しますか。まず、配列の行と列の数を取得します。行数はnumRowsでなければならないので、列数はどうでしょうか。注意深く分析した後、列の数が実際には文字列の長さsを2プラス1で割ったものであることがわかります。
3.これをジグザグに並べるにはどうすればよいですか?文字列の文字を上から下に1つずつ並べるだけです。この目的のために、文字列から文字を取得するメソッドを作成しました。実際、このプロセスはキューを使用して実行できますが、ロジックは比較的単純なので、代わりにポインターを使用します。
4.要点は、最初に最初の列をトラバースし、次に2番目の列をトラバースすることです。タイトルの要件に従って、行数が4の場合、2つの長い列の間に2つの短い列があり、行数が3の場合、短い列があるというルールを見つけることができます。 2つの長い列の間の列。実際、これは非常に単純です。つまり、短い列の部分の最初と最後の部分には要素がありません。では、現在の列が長い列なのか短い列なのかをどうやって知るのでしょうか。インデックスによって、現在のインデックスの残りをnumRows-1で取得できます。これは、0の場合は長い列です。たとえば、インデックス0、長い列、この時点ではnumRowsは3で、残りの1つは2です。2%(3-1)==05
.長い列と短い列を判断する方法はすでにわかっています。 、2つのforループを使用して、2次元配列全体を反復処理できます。長い列の場合は、上から下に書くだけです。短い列の場合は、下から上に書き込み、端の2点を超えて出てください。長い列を書き込む場合は列全体に書き込むことができますが、短い列を書き込む場合は、1つを書き込んだ後に終了して、次の列に移動する必要があります。列ごとに短い列が1つしかないためです。
6.すべての文字列が取得された後、#を書き込みます。Char配列が割り当てられていない場合、デフォルト値は'\ u0000'であるため、結果を出力するときに、2つのforループを使用して2次元配列をトラバースし、そうでないかどうかを判断するだけで済みます。または\u0000、記録します。
7.記録された文字列を返します。これは必要なZ文字列です。
public class Solution {
public string Convert(string s, int numRows) {
//(s.Length/numRows)*2-1就是Z型数组长度
//numRows就是宽度
//s的长度除以宽度就是 最长的列的个数
//Z型数组长度减去最长的列的个数 就是短列的个数
//如果传入s长度14 rows为3
//那么Z型数组长度为(14/3)*2-1=7
//最长列个数为14/3 为4
//短列为7-4 为3
//其次我们还需要用长度
if(s.Length==0||s.Length==1||numRows==1)return s;
int ArrayLength=s.Length/2+1; //Z型数组长度 7
int LongLength=(s.Length/numRows);
int ShortLength=ArrayLength-LongLength;
int between=numRows-2; //短的 //2
char[,] rows=new char[numRows,ArrayLength];
int curindex=-1; //现在放入的个数
for(int i=0;i<ArrayLength;i++){
//0-6
for(int j=0;j<numRows;j++){
//0-2
// if(curCount>=s.Length){
// rows[j,i]='#';
// continue;
// }
if((i%(between+1)!=0&&i!=0) ){
//是短列
if(numRows>2){
if(j==0||j==numRows-1){
//奇数列头尾两个不设值
rows[numRows-i%(between+1)-1,i]='#';
}else{
rows[numRows-i%(between+1)-1,i]=GetOneChar();
break;
}
}else{
rows[numRows-i%(between+1)-1,i]=GetOneChar();
break;
}
}else{
rows[j,i]=GetOneChar();
}
}
}
string ss="";
for(int i=0;i<numRows;i++){
for(int j=0;j<ArrayLength;j++){
if(rows[i,j]!='#'&&rows[i,j]!='\u0000'){
ss+=rows[i,j];
}
}
}
ss.Replace("\u0000", string.Empty);
return ss;
char GetOneChar(){
curindex++;
if(curindex>=s.Length){
return '#';
}else{
return s[curindex];
}
}
}
}
著者:モルモットXiaohuihui
著作権は著者に帰属します。商用の再版については、著者に連絡して許可を求め、非商用の再版については、出典を示してください。