面试题 02.07. 链表相交

题目

自己写的:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:

    ListNode *getIntersection(ListNode *headA, ListNode *headB, int lenA, int lenB)
    {
        int sub = lenA - lenB;

        ListNode *curA = headA, *curB = headB;
        while (sub--)
        {
            curA = curA->next;
        }
        while (curA && curB && curA != curB)
        {
            curA = curA->next;
            curB = curB->next;
        }
        return curA;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int lA = 0, lB = 0;
        ListNode *cur = headA;
        while (cur)
        {
            ++lA;
            cur = cur->next;
        }
        cur = headB;
        while (cur)
        {
            ++lB;
            cur = cur->next;
        }
        if (lA >= lB)
        {
            return getIntersection(headA, headB, lA, lB);
        }
        else
        {
            return getIntersection(headB, headA, lB, lA);
        }
    }
};

这题有一个很大的坑就是题目中说的相交的起始节点其实是指节点的地址相等,而不是节点的值相等。

其实观察仔细的话,从给的示例1应该就能看出这点:

img

输出的是8,而不是1。

后面的两个示例感觉都有点迷惑性,引导掉坑里。

我刚开始写的代码就是没明白这点,就没通过:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:

    ListNode *getIntersection(ListNode *headA, ListNode *headB, int lenA, int lenB)
    {
        int sub = lenA - lenB;

        ListNode *curA = headA, *curB = headB;
        while (sub--)
        {
            curA = curA->next;
        }
        while (curA && curB && curA->val != curB->val)
        {
            curA = curA->next;
            curB = curB->next;
        }
        return curA;
    }

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int lA = 0, lB = 0;
        ListNode *cur = headA;
        while (cur)
        {
            ++lA;
            cur = cur->next;
        }
        cur = headB;
        while (cur)
        {
            ++lB;
            cur = cur->next;
        }
        if (lA >= lB)
        {
            return getIntersection(headA, headB, lA, lB);
        }
        else
        {
            return getIntersection(headB, headA, lB, lA);
        }
    }
};

然后看了下卡哥的思路,和我差不多,不过他的代码我觉得更优,其实没必要再定义一个函数来专门针对两个链表的长度谁打谁小的问题。

卡哥代码:

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

官方题解提供了两种方法,也值得看一下,方法一是用哈希集合,方法二看的我一愣一愣的,神人也!

posted @ 2024-11-28 19:44  hisun9  阅读(2)  评论(0编辑  收藏  举报