LeetCode_160. 相交鏈表

題目

編寫一個程序,找到兩個單鏈表相交的起始節點。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //此處編寫代碼
}

例如,下面的兩個鏈表:

A:     a1 → a2
         ↘
          c1 → c2 → c3
         ↗
B:  b1 → b2 → b3
在節點 c1 開始相交。

注意:

  • 如果兩個鏈表沒有交點,返回 null.
  • 在返回結果後,兩個鏈表仍須保持原有的結構。
  • 可假定整個鏈表結構中沒有循環。
  • 程序儘量滿足 O(n) 時間複雜度,且僅用 O(1) 內存。

題解

思路: 有兩種思路,第一種是先遍歷A鏈表,將最後一個節點的next指向A的頭結點,然後用鏈表判環的方式去找環的起點即兩個鏈表的交叉點,最後要把環斷開還原鏈表。鏈表判環見141. 環形鏈表
第二種思路是先遍歷兩個鏈表,算出兩鏈表長度的差值N,然後較長鏈表先走N步然後兩鏈表同時向後遍歷,遇上相同節點即爲相交點。
note:注意鏈表爲空的情況。最後兩鏈表一定會交於NULL。

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    if (__builtin_expect(!!(!headA || !headB), 0)) return NULL;
    int lena = 0, lenb = 0, len;
    struct ListNode *p = headA, *q = headB;
    while (p != NULL) {
        lena++;
        p = p->next;
    }
    while (q) {
        lenb++;
        q = q->next;
    }
    p = headA;
    q = headB;    
    if (lena > lenb) {
        len = lena - lenb;
        while (len--) {
            p = p->next;
        }    
    } else {
        len = lenb - lena;
        while (len--) {
            q = q->next;
        }
    }
    while (p != q) {
        p = p->next;
        q = q->next;
    }
    return p;
}

ps : 這題代碼寫的好醜

LeetCode習題彙總

發佈了28 篇原創文章 · 獲贊 15 · 訪問量 7160
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章