zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    .NET正则基础之——平衡组
    正则基础之——贪婪与非贪婪模式
    正则应用之——日期正则表达式
    文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(完整版,收集,整理)
    linux c 发送邮件
    select, poll和epoll的区别(转)
    linux c 中文支持
    修改远程桌面连接端口(PortNumber)
    libhdfs编译,安装,配置,使用
    C语言字节对齐详解
  • 原文地址:https://www.cnblogs.com/i-8023-/p/11825774.html
Copyright © 2011-2022 走看看