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; }