160. 相交链表

2019-11-09 16:01:15来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。   示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。   示例 2: 输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Reference of the node with value = 2 输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。   示例 3: 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 解释:这两个链表不相交,因此返回 null。   注意: 如果两个链表没有交点,返回 null. 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。   来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。     思路1 遍历链表 A,将 A中节点对应的指针(地址),插入 set 遍历链表 B,将 B中节点对应的指针(地址),在 set 中查找,不返回 end()的第一个 地址,即交点    
 1 class Solution {
 2 public:
 3     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
 4         set<ListNode*> node_set;
 5         while (headA) {
 6             node_set.insert(headA);
 7             headA = headA->next;
 8         }
 9         while (headB) {
10             if (node_set.find(headB) != node_set.end()) { //find()没找到,返回 end()
11                 return headB;
12             }
13             headB = headB->next;
14         }
15         return NULL;
16     }
17 };

 

思路 2 计算链表长度和长度之差

  将长链表指针移动到和短链表对齐   headA 和 headB 同时移动,直到两指针指向同一节点    
 1 class Solution {
 2 public:
 3     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
 4         int list_A_len = getListLength(headA);
 5         int list_B_len = getListLength(headB);
 6         if (list_A_len > list_B_len) {
 7             headA = forwardLongList(headA, list_A_len, list_B_len);
 8         } else {
 9             headB = forwardLongList(headB, list_B_len, list_A_len);
10         }
11         while (headA && headB) {
12             if (headA == headB) {
13                 return headA;
14             }
15             headA = headA->next;
16             headB = headB->next;
17         }
18         return NULL;
19     }
20 private:
21     //计算链表长度
22     int getListLength(ListNode* head) {
23         int len = 0;
24         while (head) {
25             ++len;
26             head =  head->next;
27         }
28         return len;
29     }
30    
31     //将长链表指针向后移动,返回对齐后的位置
32     ListNode* forwardLongList(ListNode* long_head, int long_len, int short_len) {
33         int delta = long_len - short_len;
34         while (long_head && delta) {
35             long_head = long_head->next;
36             --delta;
37         }
38         return long_head;
39     }
40 };

 

测试
 1 int main(int argc, const char * argv[]) {
 2     ListNode a1(1);
 3     ListNode a2(2);
 4     ListNode b1(3);
 5     ListNode b2(4);
 6     ListNode b3(5);
 7     ListNode c1(6);
 8     ListNode c2(7);
 9     ListNode c3(8);
10     a1.next = &a2;
11     a2.next = &c1;
12     c1.next = &c2;
13     c2.next = &c3;
14     b1.next = &b2;
15     b2.next = &b3;
16     b3.next = &c1;
17     
18     Solution solve;
19     ListNode *result = solve.getIntersectionNode(&a1, &b1);
20     cout <<result->val;
21 
22     return 0;
23 }
View Code

 


原文链接:https://www.cnblogs.com/i-8023-/p/11825774.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:C++工程师养成 每日一题(vector使用)

下一篇:POJ1852