Intersection of Two Linked Lists

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.

Notes:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

1、自己算法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    if (head == NULL)
        return NULL;
    struct ListNode *tmp1 = head->next;    //这里使用了head->next;所以head == NULL判断必须放上面
    struct ListNode *tmp2 = head;
    
    if(head->next == NULL)
        return head;
    head = head->next;
    tmp2->next = NULL;
    while(head->next != NULL)
    {
        head = head->next; 
        tmp1->next = tmp2;
        tmp2 = tmp1;
        tmp1 = head;
    }
    head->next = tmp2;
    return head;
}
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *tailA = reverseList(headA);
    struct ListNode *tailB = reverseList(headB);
    struct ListNode *tmpA = NULL;
    struct ListNode *tmpB = NULL;
    struct ListNode *tmpA2 = tailA;
    struct ListNode *tmpB2 = tailB;
    while(tailA && tailB)
    {
        if(tailA == tailB)
        {
            tmpA = tailA;
            tmpB = tailB;
            tailA = tailA->next;
            tailB = tailB->next;
        }
        else
        {
            reverseList(tmpA2);
            reverseList(tmpB2);
            return tmpA;
        }
    }
    return NULL;
}
  • 先把两个链表倒过来,然后从后向前比较,找到第一个不相同的点停止,把链表再倒回来,结果出错
  • 原来问题出在了这两个链表不是完全独立的链表,所以两个链表都倒转一遍的时候,就会出错,纸上画画就知道了

2、使用网上的方法:先算出两个链表的长度,得出差值,然后长的一个先推进差值个,然后开始对比地址,出现相同就是存在,如果到最后都没有相等的,就是不存在

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    int nA = 0, nB = 0, n = 0;
    struct ListNode *tmpA = headA, *tmpB = headB;
    if(tmpA == NULL || tmpB == NULL)
        return NULL;
//得出两个的长度
    while(tmpA != NULL)
    {
        ++nA;
        tmpA = tmpA->next;
    }
    while(tmpB != NULL)
    {
        ++nB;
        tmpB = tmpB->next;
    }
    n = nA - nB;
    tmpA = headA;            //要重新回到头结点
    tmpB = headB;
    if(n > 0)
    {
        while(n--)
            tmpA = tmpA->next;
    }
    else
        {
            n = -n;
            while(n--)
                tmpB = tmpB->next;
        }
    while(tmpA != NULL)
        {
            if(tmpA == tmpB)
                return tmpA;
            else
            {
                tmpA = tmpA->next;
                tmpB = tmpB->next;
            }
        }
    return NULL;
}
posted @ 2015-09-25 21:19  dylqt  阅读(124)  评论(0编辑  收藏  举报