题目地址:

https://oj.leetcode.com/problems/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.

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.

方法:

首先,既然是时间复杂度O(n),那么就不能一个一个点那样试;

其次,既然空间复杂度要求O(1),既然就不能用stack或者unordered_map之类的数据结构来找链表交点。

那么,我们需要一个比较酷炫的trick来找交点。

先转化问题:

假设有A、B两条链表相交,请求出交点到A链表头结点的距离。(所谓距离,就是头结点走几次能到)

先看具体求法:

0、计算A链表的长度lenA

1、计算B链表的长度lenB

2、逆转A链表(关键)

3、重新计算B链表的长度newLenB

4、返回result = (newLenB - lenB + lenA - 1) / 2

具体到这道题,还需要把A链表又逆转回来,因为你不能更改链表原来的结构。然后重新读取链表,返回第result个结点就OK了。

那么这具体求法究竟是怎么来的?

自己动手试试就明白了。其实就是算出A链表结点在交点旁边的分布数,画图太麻烦了,如果有时间再补一个,或者谁不理解回复一下我就补

全部代码:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == NULL || headB == NULL)
return NULL;
int addressA; // fin of A.
int addressB; // fin of B.
int lenA = countLength(headA,&addressA);
int lenB = countLength(headB,&addressB);
if (addressA != addressB) // if has a intersect
return NULL;
ListNode *tmpHeadA = (ListNode *)addressA; // to store headA's tail for reverse.
reverseLink(headA);
int newLenB = countLength(headB,&addressB);
int toNew = findCount(lenA,lenB,newLenB);
reverseLink(tmpHeadA);
return findNthNode(headA,toNew);
} int findCount(int lenA,int lenB,int newLenB)
{
int gap = newLenB - lenB;
return (gap + lenA - ) / ;
} ListNode *findNthNode(ListNode *head,int toN)
{
int count = ;
while (toN != count)
{
head = head->next;
count ++;
}
return head;
} int countLength(ListNode *head,int *fin)
{
int count = ;
while (head)
{
*fin = (int)head;
head = head->next;
count ++;
}
return count;
} void reverseLink(ListNode *head)
{
ListNode *pre = NULL;
ListNode *now = head;
ListNode *nxt = head->next;
while ()
{
now->next = pre;
pre = now;
now = nxt;
if (nxt)
nxt = nxt->next;
else
break;
}
}
};

【原创】leetCodeOj --- Intersection of Two Linked Lists 解题报告(经典的相交链表找交点)的更多相关文章

  1. LeetCode: Intersection of Two Linked Lists 解题报告

    Intersection of Two Linked Lists Write a program to find the node at which the intersection of two s ...

  2. 【LeetCode】160. Intersection of Two Linked Lists 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 栈 日期 题目地址:https://leet ...

  3. [LeetCode] 160. Intersection of Two Linked Lists 解题思路

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  4. 160. Intersection of Two Linked Lists(剑指Offer-两个链表的第一个公共结点)

    题目: Write a program to find the node at which the intersection of two singly linked lists begins. Fo ...

  5. LeetCode 160: 相交链表 Intersection of Two Linked Lists

    爱写Bug(ID:iCodeBugs) 编写一个程序,找到两个单链表相交的起始节点. Write a program to find the node at which the intersectio ...

  6. [LintCode] Intersection of Two Linked Lists 求两个链表的交点

    Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...

  7. 2016.5.24——Intersection of Two Linked Lists

    Intersection of Two Linked Lists 本题收获: 1.链表的输入输出 2.交叉链表:这个链表可以有交叉点,只要前一个节点的的->next相同即可. 题目:Inters ...

  8. [LeetCode]160.Intersection of Two Linked Lists(2个链表的公共节点)

    Intersection of Two Linked Lists Write a program to find the node at which the intersection of two s ...

  9. 160. Intersection of Two Linked Lists【easy】

    160. Intersection of Two Linked Lists[easy] Write a program to find the node at which the intersecti ...

随机推荐

  1. oracle 密码文件文件

    密码文件作用: 密码文件用于dba用户的登录认证. dba用户:具备sysdba和sysoper权限的用户,即oracle的sys和system用户. 本地登录: 1)操作系统认证: [oracle@ ...

  2. Lua 解释器

    Lua 解释器 警告⚠️:这将是一个又臭又长的系列教程,教程结束的时候,你将拥有一个除了性能差劲.扩展性差.标准库不完善之外,其他方面都和官方相差无几的 Lua 语言解释器.说白了,这个系列的教程实现 ...

  3. 鼠标右键怎么清除Catalyst Control Center

    开始→运行→regedit→找到HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\ACE→双击并修改其键值 可以删除 ...

  4. onkeypress事件.onkeydown事件.onkeyup事件

    onkeypress事件是在按键開始按的时候发生: onkeydown事件是在按键已经按下的时候发生: onkeyup事件是在按键松开(释放)的时候发生.

  5. C编译: makefile基础

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在编译一个大型项目的时候,往往有很多目标文件.库文件.头文件以及最终的可执行文件. ...

  6. poj1236(强连通缩点)

    传送门:Network of Schools 题意:一些学校联接在一个计算机网络上,学校之间存在软件支援协议,每个学校都有它应支援的学校名单(A学校支援学校B,并不表示B学校一定支援学校A).当某校获 ...

  7. linux+nginx+mysql+php

    LNMP(linux+nginx+mysql+php)服务器环境配置   一.简介 Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为 “engine X”, 是一个高性能的 ...

  8. Groovy常见语法汇总

    一.groovy是什么 简单地说,Groovy 是下一代的java语言,跟java一样,它也运行在 JVM 中. 作为跑在JVM中的另一种语言,groovy语法与 Java 语言的语法很相似.同时,G ...

  9. 云计算分布式大数据神器Spark实战高手之旅

    从2012年1月份研究Spark到如今已经两年多的时间了. 在这两年多的时间里比較彻底的研究了Spark的源码并已经在2014年4月24日编写完毕了世界上第一本Spark书籍. 鉴于CSDN在大陆IT ...

  10. oracle的to_char中的fm

    SQL> select '|'||to_char(5,'999')||'|' from dual;  结果为:|   5| SQL> select '|'||to_char(5,'000' ...