Intersection of Two Linked Lists
本题收获:
1.链表的输入输出
2.交叉链表:这个链表可以有交叉点,只要前一个节点的的->next相同即可。
题目: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.
注意:题目中两个链表是有交叉点,只要a2,b3指向的下一个节点地址都是c1的即可。
思路:
我的思路:刚开把题目理解错了,以为是两个单链表有相同的节点。
leetcode/dicuss思路:看看网上的思路
那题目的最好解法,这技巧问题阿,遍历list1 后接着遍历list2,同时,遍历list2然后遍历list1,这样两个遍历的长度是一样的O(n+m),怎么判断相等呢?
list1: O O O O O ⑴ ⑵ ⑶
list2: □ □ □ □ ⑴ ⑵ ⑶
假如list 如上,⑴ ⑵ ⑶ 为相同的节点,那么遍历list1 这样便是这样:
O O O O O ⑴ ⑵ ⑶ □ □ □ □ ⑴ ⑵ ⑶
遍历list2 便是这样。
□ □ □ □ ⑴ ⑵ ⑶ O O O O O ⑴ ⑵ ⑶
合在一起看看:
O O O O O ⑴ ⑵ ⑶ □ □ □ □ ⑴ ⑵ ⑶
□ □ □ □ ⑴ ⑵ ⑶ O O O O O ⑴ ⑵ ⑶
好了,现在规律出来了。这个逻辑出来明显,主要麻烦是在遍历一个结束后接上第二个,直接改链表不好,所以,使用flag 控制。
算法逻辑:
- 判断list 是否有NULL 情况
- 同时遍历 两个新链表
- 如果节点地址相同,返回
- 如果不相同继续遍历
- 遍历结束返回NULL
代码:
1 class Solution { 2 public: 3 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 4 ListNode *p1 = headA, *p2 = headB; 5 if(p1 == NULL || p2 == NULL) 6 return NULL; 7 while(p1 != p2) 8 { 9 p1 = p1->next; 10 p2 = p2->next; 11 if(p1 == NULL && p2 != NULL) 12 p1 = headB; 13 if(p2 == NULL && p1 != NULL) 14 p2 = headA; 15 } 16 return p1; 17 } 18 };
我的测试代码:
代码1:是错误的理解,即两个单独的链表。
1 #include "stdafx.h" 2 #include "iostream" 3 #include "vector" 4 using namespace std; 5 6 struct ListNode 7 { 8 int val; 9 ListNode *next; 10 ListNode(int x) : val(x), next(NULL){} //what this mean 11 }; 12 13 class Solution { 14 public: 15 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 16 ListNode *p1 = headA; 17 ListNode *p2 = headB; 18 19 if (p1 == NULL || p2 == NULL) return NULL; 20 21 while (p1 != NULL && p2 != NULL && p1 != p2) { 22 p1 = p1->next; 23 p2 = p2->next; 24 if (p1 == NULL) p1 = headB->next; 25 if (p2 == NULL) p2 = headA->next; 26 //cout << p1->val << endl; 27 //cur1 = cur1->next; 28 //cout << p2->val << endl; 29 //cur2 = cur2->next; 30 //cout << cur2->val << endl; 31 // Any time they collide or reach end together without colliding 32 // then return any one of the pointers. 33 // 34 if (p1->val == p2->val) //如果是两个链表找相同点,则(p1->val ==p2->val) 35 { 36 //cout << p1 << endl; 37 return p1; 38 } 39 // 40 // If one of them reaches the end earlier then reuse it 41 // by moving it to the beginning of other list. 42 // Once both of them go through reassigning, 43 // they will be equidistant from the collision point. 44 // 45 46 if (p1 == NULL && p2 == NULL) 47 { 48 //cur2 = headA; 49 //cout << "hhh" << endl; 50 } 51 } 52 //cout << p1 << endl; 53 return p1; 54 } 55 }; 56 57 int _tmain(int argc, _TCHAR* argv[]) 58 { 59 ListNode *h1 = new ListNode(20), *h2 = new ListNode(20), *p1 = NULL, *node1 = NULL, *p2 = NULL, *node2 = NULL, *head = NULL; 60 vector<int> nums1 = { 1, 2, 3, 4 }, nums2 = { 0, 9, 7, 3, 4 }; 61 //nums1 = { 1, 2, 3, 4 }; //题目理解错误,条件给的出错, 62 //nums2 = { 0, 9, 7, 3, 4 }; 63 p1 = h1; 64 p2 = h2; 65 for (size_t i = 0; i < nums1.size(); i++) 66 { 67 node1 = new ListNode(nums1.at(i)); 68 69 if (h1 == NULL) 70 { 71 h1 = node1; 72 } 73 else p1->next = node1; 74 p1 = node1; 75 } 76 77 for (size_t j = 0; j < nums2.size(); j++) 78 { 79 node2 = new ListNode(nums2.at(j)); 80 if (h2 == NULL) 81 { 82 h2 = node2; 83 } 84 else p2->next = node2; 85 p2 = node2; 86 } 87 88 Solution solution; 89 head = solution.getIntersectionNode(h1, h2); 90 cout << head->val << endl; //为空所以出错 91 system("pause"); 92 return 0; 93 }
代码2:正确思路代码,也可以看到这两的mian函数的区别。
1 #include "stdafx.h" 2 #include "iostream" 3 #include "vector" 4 using namespace std; 5 6 struct ListNode 7 { 8 int val; 9 ListNode *next; 10 ListNode(int x) : val(x), next(NULL){} //what this mean 11 }; 12 13 /*class MyClass 14 { 15 public: 16 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 17 { 18 ListNode *cur1 = headA, *cur2 = headB; 19 //cur1 = headA, cur1 = headB; 20 //cout << cur1 << endl; 21 if (cur1 == NULL || cur2 == NULL) 22 return NULL; 23 24 while (cur1 != cur2) 25 { 26 //cout << cur1 << endl; 27 cur1 = cur1->next; 28 //cout << cur1->val << endl; 29 cur2 = cur2->next; 30 //cout << cur2->val << endl; 31 if (cur1 == NULL && cur2 != NULL) 32 { 33 //cout << cur1 << endl; 34 cur1 = headB; 35 //cout << cur1->val << endl; 36 } 37 if (cur2 == NULL && cur1 != NULL) 38 { 39 cur2 = headA; 40 //cout << cur2->val << endl; 41 } 42 if (cur2 == NULL && cur1 == NULL) //测试是否进入空指针 43 { 44 //cur2 = headA; 45 cout << "hhh" << endl; 46 } 47 } 48 return cur1; 49 //cout << cur1->val << endl; 50 } 51 };*/ 52 class Solution { 53 public: 54 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 55 ListNode *p1 = headA; 56 ListNode *p2 = headB; 57 58 if (p1 == NULL || p2 == NULL) return NULL; 59 60 while (p1 != NULL && p2 != NULL && p1 != p2) { 61 p1 = p1->next; 62 p2 = p2->next; 63 if (p1 == NULL) p1 = headB->next; 64 if (p2 == NULL) p2 = headA->next; 65 //cout << p1->val << endl; 66 //cur1 = cur1->next; 67 //cout << p2->val << endl; 68 //cur2 = cur2->next; 69 //cout << cur2->val << endl; 70 // Any time they collide or reach end together without colliding 71 // then return any one of the pointers. 72 // 73 if (p1 == p2) //如果是两个链表找相同点,则(p1->val ==p2->val) 74 { 75 //cout << p1 << endl; 76 return p1; 77 } 78 // 79 // If one of them reaches the end earlier then reuse it 80 // by moving it to the beginning of other list. 81 // Once both of them go through reassigning, 82 // they will be equidistant from the collision point. 83 // 84 85 if (p1 == NULL && p2 == NULL) 86 { 87 //cur2 = headA; 88 //cout << "hhh" << endl; 89 } 90 } 91 //cout << p1 << endl; 92 return p1; 93 } 94 }; 95 96 int main() 97 { 98 ListNode *head1, *head2, *node1, *node2, *node3,*node4,*node5,*head; 99 node1 = new ListNode(2); //这样的赋值,链表就会有交叉点了,和题目一样 100 node2 = new ListNode(5); 101 node3 = new ListNode(8); 102 node4 = new ListNode(7); 103 node5 = new ListNode(8); 104 105 head1 = node1; 106 head1->next = node2; 107 node2->next = node5; 108 node5->next = NULL; 109 110 head2 = node3; 111 head2->next = node4; 112 node4->next = node5; 113 node5->next = NULL; 114 115 Solution solution; 116 head = solution.getIntersectionNode(head1, head2); 117 cout << head->val << endl; 118 system("pause"); 119 return 0; 120 }