【原创】leetCodeOj --- Intersection of Two Linked Lists 解题报告(经典的相交链表找交点)

题目地址:

https://oj.leetcode.com/problems/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.

方法:

 

首先,既然是时间复杂度O(n),那么就不能一个一个点那样试;

其次,既然空间复杂度要求O(1),既然就不能用stack或者unordered_map之类的数据结构来找链表交点。

那么,我们需要一个比较酷炫的trick来找交点。

 

先转化问题:

假设有A、B两条链表相交,请求出交点到A链表头结点的距离。(所谓距离,就是头结点走几次能到)

 

先看具体求法:

0、计算A链表的长度lenA

1、计算B链表的长度lenB

2、逆转A链表(关键)

3、重新计算B链表的长度newLenB

4、返回result = (newLenB - lenB + lenA - 1) / 2

 

具体到这道题,还需要把A链表又逆转回来,因为你不能更改链表原来的结构。然后重新读取链表,返回第result个结点就OK了。

那么这具体求法究竟是怎么来的?

 

自己动手试试就明白了。其实就是算出A链表结点在交点旁边的分布数,画图太麻烦了,如果有时间再补一个,或者谁不理解回复一下我就补

 

全部代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if (headA == NULL || headB == NULL)
            return NULL;
        int addressA; // fin of A.
        int addressB; // fin of B.
        int lenA = countLength(headA,&addressA);
        int lenB = countLength(headB,&addressB);
        if (addressA != addressB) // if has a intersect
            return NULL;
        ListNode *tmpHeadA = (ListNode *)addressA; // to store headA's tail for reverse.
        reverseLink(headA);
        int newLenB = countLength(headB,&addressB);
        int toNew = findCount(lenA,lenB,newLenB);
        reverseLink(tmpHeadA);
        return findNthNode(headA,toNew);
    }
    
    int findCount(int lenA,int lenB,int newLenB)
    {
        int gap = newLenB - lenB;
        return (gap + lenA - 1) / 2;
    } 
    
    ListNode *findNthNode(ListNode *head,int toN)
    {
        int count = 0;
        while (toN != count)
        {
            head = head->next;
            count ++;
        }
        return head;
    }
    
    int countLength(ListNode *head,int *fin)
    {
        int count = 0;
        while (head)
        {
            *fin = (int)head;
            head = head->next;
            count ++;
        }
        return count;
    }
    
    void reverseLink(ListNode *head)
    {
        ListNode *pre = NULL;
        ListNode *now = head;
        ListNode *nxt = head->next;
        while (1)
        {
            now->next = pre;
            pre = now;
            now = nxt;
            if (nxt)
                nxt = nxt->next;
            else
                break;
        }
    }
};

 

posted on 2014-12-08 17:48  shadowmydx'sLab  阅读(166)  评论(0编辑  收藏  举报

导航