データ構造とアルゴリズム: リンクリストの交差、交差点を見つける

データ構造とアルゴリズム: リンクリストの交差、交差点を見つける

[[441326]]

リンクリストの交差

LeetCode の問題へのリンク: https://leetcode-cn.com/problems/intersection-of-two-linked-lists-lcci

単一リンク リストの 2 つのヘッド ノード headA と headB が指定されている場合、2 つの単一リンク リストが交差する開始ノードを見つけて返します。 2 つのリンク リストに交差がない場合は null を返します。

この図は、2 つのリンク リストがノード c1 で交差し始めていることを示しています。

タイトル データにより、チェーン構造全体にループがないことが保証されます。

関数が返された後、リンク リストは元の構造を維持する必要があることに注意してください。

例1:

例2:

例3:

アイデア

簡単に言えば、2 つのリンク リストの交差ノードのポインタを見つけることです。ここで学生は、交差点は値が等しいのではなく、ポインタが等しいことに注意する必要があります。

例として、ノード要素の値が等しい場合、ノード ポインターも等しいと想定します。

次の 2 つのリンク リストを見てください。現在、curA はリンク リスト A のヘッド ノードを指し、curB はリンク リスト B のヘッド ノードを指しています。

2 つのリンク リストの長さと 2 つのリンク リストの長さの差を計算し、図に示すように、curA を curB の末尾に一致する位置に移動します。

この時点で、curA と curB が同じかどうかを比較できます。同じでない場合は、curA と curB を同時に後方に移動します。curA == curB の場合、交差が見つかります。

それ以外の場合はループが終了し、null ポインターを返します。

C++ コードは次のとおりです。

  1. クラスソリューション{
  2. 公共
  3. リストノード *getIntersectionNode(リストノード *headA、リストノード *headB) {
  4. リストノード* curA = headA;
  5. リストノード* curB = headB;
  6. 整数lenA = 0、lenB = 0;
  7. while (curA != NULL ) { // リンクリストAの長さを見つける
  8. lenA++;
  9. curA = curA->次へ;
  10. }
  11. while (curB != NULL ) { // リンクリストBの長さを見つける
  12. lenB++;
  13. curB = curB->次へ;
  14. }
  15. curA = ヘッドA;
  16. カーソルB = ヘッドB;
  17. // curA を最長リンクリストの先頭とし、lenA をその長さとする
  18. (長さB>長さA)の場合{
  19. (lenA、lenB)を交換する。
  20. スワップ(curA, curB);
  21. }
  22. // 長さの差を求める
  23. intギャップ = lenA - lenB;
  24. // curA と curB を同じ開始点にします(終了位置は揃えます)
  25. while (ギャップ--) {  
  26. curA = curA->次へ;
  27. }
  28. // curA と curB を走査し、同じであれば直接戻ります
  29. (curA != NULL ) の場合 {
  30. もしcurA == curBの場合{
  31. curAを返します
  32. }
  33. curA = curA->次へ;
  34. curB = curB->次へ;
  35. }
  36. 戻る  NULL ;
  37. }
  38. };
  • 時間の計算量:
  • 空間の複雑さ:

その他の言語

ジャワ

  1. パブリッククラスソリューション{
  2. パブリックListNode getIntersectionNode(ListNode headA、ListNode headB) {
  3. リストノード curA = headA;
  4. リストノード curB = headB;
  5. 整数lenA = 0、lenB = 0;
  6. while (curA != null ) { // リンクリストAの長さを見つける
  7. lenA++;
  8. curA = curA.next ;
  9. }
  10. while (curB != null ) { // リンクリストBの長さを見つける
  11. lenB++;
  12. curB = curB.next ;
  13. }
  14. curA = ヘッドA;
  15. カーソルB = ヘッドB;
  16. // curA を最長リンクリストの先頭とし、lenA をその長さとする
  17. (長さB>長さA)の場合{
  18. //1. lenA、lenBを入れ替えます。
  19. int tmpLen = lenA;
  20. lenA = lenB;
  21. lenB = tmpLen;
  22. //2. swap(curA, curB);
  23. リストノード tmpNode = curA;
  24. curA = curB;
  25. curB = tmpNode;
  26. }
  27. // 長さの差を求める
  28. intギャップ = lenA - lenB;
  29. // curA と curB を同じ開始点にします(終了位置は揃えます)
  30. while (ギャップ--> 0) {  
  31. curA = curA.next ;
  32. }
  33. // curA と curB を走査し、同じであれば直接戻ります
  34. (curA != null ) の場合 {
  35. もしcurA == curBの場合{
  36. curAを返します
  37. }
  38. curA = curA.next ;
  39. curB = curB.next ;
  40. }
  41. 戻る ヌル;
  42. }
  43.  
  44. }

パイソン

  1. クラスソリューション:
  2. def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
  3. 「」 「
  4. 速度の法則によれば、より速く歩く人はより遅く歩く人に必ず追いつくでしょう。
  5. この問題では、いくつかのリンク リストは短く、1 つのリンクを歩き終えた後、別のリンク リストを歩きます。これは、より速く移動するポインタとして理解できます。
  6.  
  7. 次に、リンクされたリストの 1 つが完了したら、もう一方のリンクされたリストに進みます。交差点があれば、最終的には同じになる
  8. ロケーションエンカウンター
  9. 「」 「
  10. cur_a, cur_b = headA, headB # a と b の代わりに 2 つのポインタを使用します
  11.  
  12.  
  13. cur_a != cur_b の場合:
  14. cur_a = cur_a.next if cur_a else headB # a が終了したら b に切り替える
  15. cur_b = cur_b.next if cur_b else headA # 同様に、bが終了したらaに切り替えます
  16.  
  17. cur_aを返す

行く

  1. getIntersectionNode関数(headA, headB *ListNode) *ListNode {
  2. curA := headA
  3. カーソルB := ヘッドB
  4. 長さA、長さB:=0、0
  5. // AとBの長さを求める
  6. curA != nil {の場合
  7. curA = curA.次へ 
  8. lenA++
  9. }
  10. curB != nil の場合
  11. curB = curB.次へ 
  12. 長さB++
  13. }
  14. var ステップint  
  15. var 高速、低速 *ListNode
  16. // 長さの差を要求し、長い方のリンクリストを先にします
  17. lenA > lenBの場合{
  18. ステップ = lenA - lenB
  19. 速い、遅い = headA、headB
  20. }それ以外{
  21. ステップ = lenB - lenA
  22. 速い、遅い = headB、headA
  23. }
  24. i:=0の場合; i < ステップ; i++ {
  25. 速い = 速い。次へ 
  26. }
  27. // 2つのリンクリストを走査し、同じものを見つけたら走査から抜け出す
  28. 速い!= 遅い {
  29. 速い = 速い。次へ 
  30. 遅い = 遅い。次へ 
  31. }
  32. 早く戻る
  33. }

ジャバスクリプト

  1. var getListLen =関数(head) {
  2. len = 0、cur = headとします。
  3. while(cur) {
  4. 長さ++;
  5. cur = cur.next ;
  6. }
  7. 長さを返します
  8. }
  9. var getIntersectionNode =関数(headA, headB) {
  10. curA = headA、curB = headB とします。
  11. lenA = getListLen(headA)、
  12. lenB = getListLen(headB);
  13. lenA < lenB の場合
  14. [curA, curB] = [curB, curA];
  15. [lenA, lenB] = [lenB, lenA];
  16. }
  17. i = lenA - lenB とします。
  18. i -- > 0 の 
  19. curA = curA.next  
  20. }
  21. curA && curA !== curB の場合
  22. curA = curA.next ;
  23. curB = curB.next ;
  24. }
  25. curAを返します
  26. };

<<:  信じられない! XiaoIceのデジタルツイン仮想人物は70日間ライブ放送されましたが、誰もそれが本物の人間ではないことに気づきませんでした

>>:  AIをうまく活用したいなら、この2つの問題を早急に解決しなければなりません!

ブログ    
ブログ    

推薦する

分散型ディープラーニングの新たな進歩:「分散」と「ディープラーニング」の真の統合

近年、急速に発展している人工知能の分野のひとつであるディープラーニングは、NLP、画像認識、音声認識...

...

...

...

Google の社内機械学習プロジェクト「Project Ninja」の秘密を解明します。

すべての製品に人工知能を統合したい場合は、強力な機械学習チームを育成する必要があります。 Googl...

新型コロナウイルスによりスマートシティがさらにスマート化

[[373550]]人工知能は、都市をよりスマートで効率的な仕事と生活の場へと変革する道を開きます。...

イラストレーターが10年後の情景を描く、ロボットが人間に取って代わり、38%の人が解雇に直面

科学技術の発展にはいつも驚かされます。携帯電話がいつからこんなにスマートになったのか、コンピューター...

ニューロンクラスタリングはAIの学習戦略をシミュレートできる

人間や機械がタスクをよりうまく実行できるようになるたびに、証拠の痕跡が残ります。パフォーマンス向上の...

百度の主任科学者アンドリュー・ン氏が辞任を発表

[[186234]] 3月22日、百度のトップ科学者アンドリュー・ン氏は、英語のセルフメディアプラッ...

Googleの人工知能研究所DeepMindがカナダで研究者を募集

2014年にグーグルが買収したロンドンを拠点とする人工知能研究所ディープマインドは、世界最高のAI研...

旅行業界における機械学習と AI: 5 つの重要な業界ユースケース

旅行を計画していると想像してください。 数十年前であれば、旅行先や宿泊施設の選択肢を調べたり、航空券...

...

人工知能は企業マーケティングの未来を変えるのか?

企業マーケティングにおける人工知能の利点AI を取り巻くメディアの多くは否定的ですが、AI は企業の...

知恵くんの“いいとこ”が明らかに!初のユニバーサルな具現化ベースモデル、ロボットは「理解はできるができない」状態に別れを告げる

先週金曜日、知会君は微博で「来週は良いものがリリースされる」と発表した。 「来週」になって間もなく、...