zoukankan      html  css  js  c++  java
  • 160. Intersection of Two Linked Lists(剑指Offer-两个链表的第一个公共结点)

    题目:

    Write a program to find the node at which the intersection of two singly linked lists begins.

    For example, the following two linked lists:

    A:          a1 → a2
                       ↘
                         c1 → c2 → c3
                       ↗            
    B:     b1 → b2 → b3

    begin to intersect at node c1.

    思路1:

    若两个链表具有交点:1.链表的长度差=相交前的长度差;2.两个链表的最后一个节点相同

    因此,具体步骤如下:

    1.先计算出两个链表的长度,并得到它们的长度差。

    2.在计算长度的过程中,若发现两个链表的最后一个节点不相等,则证明它们没有交点。

    3.相对长的链表头部向前移动和长度差大小一样的节点后,两个链表的头部一起向前移动,最终得到交点。

    代码1:

     1 struct ListNode {
     2     int val;
     3     ListNode *next;
     4     ListNode(int x) :
     5             val(x), next(NULL) {
     6 
     7     }
     8 };
     9 class Solution {
    10 public:
    11     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    12         if (headA == NULL || headB == NULL) {
    13             return NULL;
    14         }
    15         int i;
    16         int lenA = 1;
    17         int lenB = 1;
    18         ListNode *tempA = headA;
    19         while (tempA->next != NULL) {
    20             tempA = tempA->next;
    21             lenA++;
    22         }
    23         ListNode *tempB = headB;
    24         while (tempB->next != NULL) {
    25             tempB = tempB->next;
    26             lenB++;
    27         }
    28         if (tempA != tempB) {
    29             return NULL;
    30         }
    31         if (lenA > lenB) {
    32             for (i = 0; i < lenA - lenB; i++) {
    33                 headA = headA->next;
    34             }
    35         } else if (lenA < lenB) {
    36             for (i = 0; i < lenB - lenA; i++) {
    37                 headB = headB->next;
    38             }
    39         }
    40         while (headA != headB) {
    41             headA = headA->next;
    42             headB = headB->next;
    43         }
    44         return headA;
    45     }
    46 };

    思路2:

      思路1需要分别计算链表的长度,思路2则不需要计算长度。用两个指针扫描两个链表,最终两个指针到达NULL或者到达公共结点。

      假设链表的长度分别为len1和len2,相交后的公共长度为len。长度短的链表优先完成扫描后再去扫描长度长的链表;长度长的链表完成扫描后,去扫描长度短的链表,当两个指针相遇时,指针1走过的长度为len1+len2-len,指针2走过的长度为len2+len1-len,由此可见指针1和指针2走过了相同的长度。

      我们分4种情况讨论两个链表相交的情况。

    • 两个链表长度相同且无公共交点,此时返回NULL;
    • 两个链表长度相同且有公共交点,只需要遍历一遍就可以得到公共交点;
    • 两个链表长度不同且无公共交点,两遍扫描后返回NULL;
    • 两个链表长度不同且有公共交点,在第二遍扫描的过程中可以相遇。

    代码2:

     1 /*
     2 struct ListNode {
     3     int val;
     4     struct ListNode *next;
     5     ListNode(int x) :
     6             val(x), next(NULL) {
     7     }
     8 };*/
     9 class Solution {
    10 public:
    11     ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
    12         if(pHead1 == NULL || pHead2 == NULL)
    13             return NULL;
    14         
    15         ListNode *p1 = pHead1;
    16         ListNode *p2 = pHead2;
    17         while(p1 != p2){
    18             if(p1 != NULL)
    19                 p1 = p1->next;
    20             else
    21                 p1 = pHead2;
    22              
    23             if(p2 != NULL)
    24                 p2 = p2->next;
    25             else
    26                 p2 = pHead1;
    27         }
    28         return p1;
    29     }
    30 };
  • 相关阅读:
    ubuntu: no module named _sqlite
    mysql慢查询分析工具 pt-query-digest
    vue中的时间修饰符stop,self
    面试题 —— Ajax的基本原理总结
    es6笔记 day6-Symbol & generator
    类(class)和继承
    es6笔记 day4---模块化
    es6笔记 day3---Promise
    es6笔记 day3---对象简介语法以及对象新增
    es6笔记 day3---数组新增东西
  • 原文地址:https://www.cnblogs.com/sindy/p/6829390.html
Copyright © 2011-2022 走看看