20200202 千年に一度の対称性の日、すべての「回文アルゴリズム」をキャッチする時が来ました!

20200202 千年に一度の対称性の日、すべての「回文アルゴリズム」をキャッチする時が来ました!

[[313923]]

今日は2020年2月2日、「千年に一度の対称の日」として知られています。20200202は表でも裏でも同じで、どちらも「愛しています、愛しています」という意味です。多くの新婚夫婦が今日を結婚証明書を取得する日として選んだが、肺炎のため、いくつかの場所では今日の予約がキャンセルされた。

しかし、今日はこの日の意味について話すのではなく、テクノロジー関連のトピックについて話しましょう。

20200202 このように順方向と逆方向で同じ文字列を、アルゴリズムでは「回文」と呼びます。構造が異なるため、回文数、回文文字列、回文リンクリストなどに分類されます。

これにより、Leetcode のアルゴリズムにいくつかの問題が発生します。今日、他の人が結婚証明書を取得する日に、「回文」に関連するアルゴリズムの問​​題を確認します。

1. 回文文字列を検証する

今日の日付を文字列で表すと、「20200202」となり、回文文字列になります。

したがって、回文文字列であるかどうかを確認するメソッドを記述する場合、最も簡単な方法は文字列を反転して比較することです。

  1. ブール型isPalindrome(文字列s) {
  2. 新しい StringBuilder(s).reverse().equals(s)を返します
  3. }

しかし、ほとんどの場合、API を直接使用することはできません。それ以外では、2 つのポインターを使用して、文字列の前後方向から内側にクランプする方法がより一般的です。

  1. ブール型isPalindrome(文字列s) {
  2. 整数i = 0;
  3. int j = s.length() - 1;
  4. i < j の場合
  5. if (文字.toLowerCase(s.charAt(i) !=文字.toLowerCase(s.charAt(j))) {
  6. 戻る 間違い;
  7. }
  8. 私は++;
  9. j --;  
  10. }
  11. 戻る 真実;
  12. }

ロジックはシンプルで、1 つのループと 2 つのポインターで完了します。

ただし、これは文字列なので、文字列の長さを取得するのは簡単です。そのため、一般的なアルゴリズムの問​​題では、いくつかの追加条件が追加され、難易度が上がります。

たとえば、Leetcode の「125. 回文を検証する」では、指定された文字列にスペースが含まれています。

この場合、前のソリューションを修正するだけです。 2 つのポインターが移動しているときにスペースに遭遇すると、もう 1 ステップ進みます。

  1. パブリックブール値isPalindrome(文字列s) {
  2. int i = 0、j = s.length() - 1;
  3. i < j の場合{
  4. while(i < j && !文字.isLetterOrDigit(s.charAt(i)))
  5. 私は++;
  6. while(i < j && !文字.isLetterOrDigit(s.charAt(j)))
  7. j --;  
  8. if(文字.toLowerCase(s.charAt(i)) !=
  9. 文字.toLowerCase(s.charAt(j)))
  10. 戻る 間違い;
  11. i++; j --;  
  12. }
  13. 戻る 真実;
  14. }

isLetterOrDigit() を使用すると、現在の文字が文字と数字のみであるかどうかを直接判断できます。

文字列の回文アルゴリズムについては、125 のほか、Leetcode の質問 680 も回文文字列に属します。興味があれば、調べてみてください。

2. 回文の数を確認する

回文文字列に数字のみが含まれている場合は、20200202 などの回文数字になることもあります。

回文を検証する場合、比較的簡単な方法は、回文を文字列に変換してから、文字の回文を検証するためのアルゴリズム パターンを適用することです。しかし、これは数字の特性を利用していません。

これは数値なので、割り算 / と剰余 % を使用して数値の後半部分を取り出し、反転してから、2 つの数値が等しいかどうかを比較できます。

  1. パブリックブール値isPalindrome( int x) {
  2. (x < 0 || (x % 10 == 0 && x != 0))の場合
  3. 戻る 間違い;
  4. int戻された数値 = 0;
  5. while (x > 戻された数値) {
  6. 戻された数値 = 戻された数値 * 10 + x % 10;
  7. x /= 10;
  8. }
  9. x == 戻された数値 || x == 戻された数値 / 10 を返します
  10. }

簡単な説明:

1. まず簡単な検証を行ってください。 0 より大きい非ゼロの数値の一の位に 0 がある場合、それは間違いなく回文ではありません。対応する回文の位置はこの数値の最上位ビットであり、最上位ビットは 0 にならないためです。

2. ループを通じて、各ループで反転された数字がビットごとに生成され、元の数字の最下位ビットが削除されます。

3. ループが終了した場合、後半部分が反転されたことを意味します。次に、数値の長さが奇数か偶数かという 2 つのケースを検討します。次に、元の数値 x と、後半部分を反転した反転した数値 (reverseNumber) が同じかどうかを判断します。

ちなみに、この質問は、Leetcode の「9. 回文」の質問です。

3. 回文リストを確認する

回文文字列と回文数について説明したので、次は回文連結リストについて見てみましょう。

単一リンクリストのような特殊な構造の場合、その長さを決定するには O(n) の計算量が必要であり、先行ポインタが存在しないため、ダブルポインタを使用して前後をクランプする方法は使用できません。

もちろん、計算のためにおなじみの回文数や回文文字列に変換することもできますが、これもリンクリストの特性を利用していません。

回文リンク リストを検証するシナリオでは、高速ポインターと低速ポインターを使用してリンク リストの中間ノードを見つけ、元のリンク リストの半分を逆にしてから比較を開始できます。

効率性を高めるために、これら 2 つのステップを 1 つのループに組み合わせることができます。

  1. パブリックブール値isPalindrome(ListNode head) {
  2. if(head == null || head.next == null ) {
  3. 戻る 真実;
  4. }
  5. ListNode 遅い = ヘッド、速い = ヘッド;
  6. ListNode pre = head、prepre = null ;
  7. while ( fast != null && fast.next != null ) {
  8. pre = 遅い;
  9. 遅い = slow.next ;
  10. 高速= fast.next.next ;
  11. pre.next = prepre;
  12. prepre = プレ;
  13. }
  14. // fast がnullでない場合は奇数なので増分する必要があることを意味します
  15. if (fast != null ) {
  16. 遅い = slow.next ;
  17. }
  18. // このとき、preは元のリンクリストの前半を反転したサブリンクリストです
  19. // slow は元のリンクリストの中間ノードです
  20. while(pre != null && slow != null ) {
  21. if(pre.val != slow.val) {
  22. 戻る 間違い;
  23. }
  24. pre = pre.next ;
  25. 遅い = slow.next ;
  26. }
  27. 戻る 真実;
  28. }

最初のループの後、低速ノードはリンク リストの中央を指し、pre は元のリンク リストの前半のサブリンク リストを反転します。

次に、while ループを使用して、それらを 1 つずつ比較することで、必要な結果を得ることができます。

ちなみに、この質問は、Leetcode の「234. 回文連結リスト」です。

4. まとめの時間

今日はここまでです。20200202では回文に関するアルゴリズムの問​​題をいくつか確認しました。回文問題を文字列、数字、リンクリストの3方向から横に見ていった結果、どのようなルールがまとめられるでしょうか?コメント欄で議論をお待ちしています。

感染症の流行により、明日から多くの友人が在宅勤務に切り替えることになります。皆様のご多幸をお祈りいたします。

<<:  新型コロナウイルスが猛威を振るう中、AI技術は流れを変えることができるのか?

>>:  クラウドプラットフォームにおける人工知能の応用は2020年に爆発的な成長を示すだろう

ブログ    
ブログ    

推薦する

...

AIがコスト削減、生産性、雇用に与える影響

AI を活用して雇用を減らし、コストを削減する方法を考えている企業は、間違っていると思います。最近、...

自動運転車は「交通渋滞をさらに悪化させる可能性がある」

西オーストラリア大学の研究者らは、交通渋滞を緩和するために設計された無人運転車が逆の効果をもたらして...

ブロックチェーンにおける主流のコンセンサスアルゴリズムの簡単な分析

プルーフ・オブ・ワーク最も一般的なブロックチェーンのコンセンサス アルゴリズムは、ビットコインのプル...

これほど長い時間が経ったのに、なぜ物流ロボットは何千もの家庭に導入されていないのでしょうか?

先日終了したCESで、ドイツのコンチネンタルAGは、新しい物流ロボット、荷物配達ロボット犬「ANYM...

超速い! ByteDanceが配列推論エンジンLightSeqをオープンソース化

これは、Transformer や GPT などの複数のモデルの高速推論を完全にサポートする業界初の...

マイクロソフト、学習者の読解力向上を支援する独立AIツール「リーディングコーチ」を発表

IT Homeは1月19日、マイクロソフトが最近、学生向けの新しい生成AIツール「Reading C...

...

工業情報化部:我が国のAIコア産業規模は5000億元に達し、2,500以上のデジタルワークショップとスマートファクトリーが建設されました

2023年中国(太原)人工知能会議が本日、山西省太原で開幕しました。中国工業情報化部科学技術部の任愛...

Cloudera のチーフアーキテクト Doug Cutting が Hadoop と人工知能について語る

[51CTO.com オリジナル記事] Doug Cutting 氏はオープンソース コミュニティに...

AIとクラウドワークロードがデータセンターの需要を牽引

JLLの新しいレポートでは、人工知能とエッジコンピューティングの採用が増加するにつれて、データセンタ...

...

AIツアーはAIIA AI開発者会議のサポートで終わりに近づいています

強力なコンピューターと複雑かつ絶えず変化する人間の知性が出会うと、どのような火花が散るのでしょうか?...