LeetCode 05最長の回文サブストリング

タイトル説明

説明:

文字列sを指定して、sで最も長い回文の部分文字列を見つけます。sの最大長は1000と想定できます。

例1:

入力:「babad」
出力:「bab」
注:「aba」も有効な回答です。

例2:

入力: "cbbd"
出力: "bb"

普通の暴力

分析:

  • 最長の回文列を見つけます。回文文字列には奇数文字列と偶数文字列の2つの形式があり、左から右に状況を列挙して、最も長い文字列を返すだけです。
  • コードを書くときは、境界を越えないように境界の問題に注意してください。適切な番号の文字列を返します。
  • Stringは不変のクラスであるため、つなぎ合わせるのにString型を使用しないでください。各つがいは一緒に新しい文字列を生成し、複数の部分を一緒にすると効率が非常に低くなります。

パスコード:

public String longestPalindrome(String s) {
    
    
		int max = 0;
		String va = "";
		if (s.length() > 0)
			va = s.charAt(0) + "";
		for (int i = 0; i < s.length() - 1; i++) {
    
    
			int l = i, r = i;//奇数个回文串
			while (l >= 0 && r <= s.length() - 1) {
    
    
				if (s.charAt(l) == s.charAt(r)) {
    
    
					l--;
					r++;
				} else {
    
    
					break;
				}
			}
			if (r - l + 1 > max) {
    
    
				max = r - l + 1;
				va = s.substring(l+1, r );
			}
			l = i;r = i + 1;//偶数个回文串
			if (s.charAt(i) == s.charAt(i + 1)) {
    
    
				while (l >= 0 && r <= s.length() - 1) {
    
    
					if (s.charAt(l) == s.charAt(r)) {
    
    
						l--;
						r++;
					} else {
    
    
						break;
					}
				}
			}
			if (r - l + 1 > max) {
    
    
				max = r - l + 1;
				va = s.substring(l+1, r );
			}

		}
		return va;
	}

センタースプレッド

最長の回文列見つけるための最適化された計画はありますか?

まず、可能な限り最長の発生場所はどこですか?

  • もちろん、最も長いものは中央の位置に表示されます。

ここに画像の説明を挿入
最大長が最初に見つかった場合、それより長くすることはできない他の回文ストリングを見つける必要がありますか?

  • もちろん違います。

より短い回文を検索する必要がないことを決定するためにどのような方法を使用できますか?

  • 中央から両側に向かって検索します。最大の回文構造の長さは最大です。
  • ポイントから境界の1つまでの距離の2倍が、両側に広がるときに最長のパリンドロームの最大長より明らかに短い場合、計算する必要はありません。直接停止できます。

ここに画像の説明を挿入

ただし、特定のコード実装に関しては、いくつかの制限と特別な状況に注意を払う必要があります。ACコードは次のとおりです。

// 法二,中间扩散
	public static String getmaxhuiwen(int l,int r,String s) {
    
    
		if(l>r)return"";
		while (l >= 0 && r <= s.length() - 1) {
    
    
			if (s.charAt(l) == s.charAt(r)) {
    
    
				l--;
				r++;
			} else {
    
    
				break;
			}
		}
		return s.substring(l+1, r);
		
	}
	public  static String longestPalindrome(String s) {
    
    
		int max = 0;
		String va = "";
		if(s.length()<2)return s;//""和"a"
		int mid = (s.length()-1) / 2;//中间(偶数左侧,奇数中间)
		for (int i = 0; i < mid+1; i++) {
    
    
			
			int l = mid - i, r = l;//左奇数个
			String s1=getmaxhuiwen(l, r, s);
			va=va.length()>s1.length()?va:s1;
			l=mid-i;r=l+1;//左偶数个
			s1=getmaxhuiwen(l, r, s);
			va=va.length()>s1.length()?va:s1;
			l=mid+i;r=l;//右奇数个
			s1=getmaxhuiwen(l, r, s);
			va=va.length()>s1.length()?va:s1;
			l=mid+i;r=l+1;//右偶数个
			s1=getmaxhuiwen(l, r, s);
			va=va.length()>s1.length()?va:s1;
			max=va.length();//最大回文长度
			if(max>(mid-i+1)*2)//找不到更长直接返回
			{
    
    
				break;
			}
			
		}
		return va;
	}

この場合、効率は良好です。
ここに画像の説明を挿入

結論

問題解決領域については、動的プログラミングの方法を提案する人もいますが、動的プログラミングではこの問題の効率はあまり改善されません。ここでは紹介しません。

回文の文字列を求めるための馬車のアルゴリズムもあります。後で学習と理解の特別な記録を書くので、ご期待ください。

最後に、いいと感じた場合は、3回連続して「いいね」、「フォロー」、「収集」を忘れないでください。作成者のWeChatパブリックアカウント:bigsaiグループに返信して、チェックインアクティビティに参加し、2週間目のチェックインを開始します。

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_40693171/article/details/107963480