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

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

[[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つの問題を早急に解決しなければなりません!

ブログ    
ブログ    
ブログ    

推薦する

予測分野における人工知能技術の応用

社会の発展と科学技術の進歩に伴い、人工知能技術が人類に与える影響は日々増大しており、その応用分野は拡...

月間 30 万個の H100 チップ、Nvidia は Intel にチップの製造を依頼しているのでしょうか? CoWosの生産能力が低すぎるからといって

TSMCの生産能力不足により、Nvidiaはチップ製造をIntelに頼らざるを得なくなったのか? T...

...

英国、今年末までに無人運転車の公道走行を許可へ

4月29日、外国メディアの報道によると、英国運輸省は水曜日、自動車線維持システム(ALK)を搭載した...

人工知能がファッションデザインと生産を変革

人工知能とロボット工学がファッション業界に変化をもたらしています。市場分析からカスタムデザイン、無駄...

...

自動運転車の安全基準を緩和?米国上院議員の提案は拒否された

最近、ジョー・バイデン米大統領は1740億ドルの電気自動車提案を行った。バイデン氏は、米国民に電気自...

「AI+コンピューティングパワー」が海外企業に「活力」を与えた

海外に進出する企業は、さまざまな市場のニーズをより正確に理解し、適応するために、大量の国境を越えたデ...

小さなモデル、大きなトレンド! Googleは2つのモデルを提案した。音量は7倍に減少し、速度は10倍に増加する。

[[426899]]ニューラル ネットワーク モデルとトレーニング データのサイズが大きくなるにつ...

機械学習トレーニングマニュアル: 頑固なブロンズから最強の王へ

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

AI人材の世界的な需要が急増、一部の職種では年間40万ドル近くを稼ぐ

6月19日のニュース:AI産業の急速な発展に伴い、テクノロジー業界のAI人材に対する需要も高まってい...

67トピック、11528の質問、新しい中国の大規模モデルマルチタスクベンチマークCMMLUがリリースされました

MBZUAI、上海交通大学、Microsoft Research Asia は協力して、包括的な中国...

1枚の写真を2分で3Dに変換します。テクスチャ品質とマルチビューの一貫性:新しいSOTA|北京大学が制作

写真を 3D に変換するのにかかる時間はわずか2 分です。さまざまな視点から見て、質感の品質と一貫性...

AIストレージプラットフォームが機械学習とデータ分析のニーズを満たす方法

機械学習と AI タスクの実行方法や環境内でのデータの収集方法に応じて、組織はどの AI ストレージ...