编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:

在节点 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) 内存。

在解题之前我发现了一个问题:示例一 中相交链表的起始节点是8,而不是1,经过仔细思考,才理解。

这里的相交不是指值一样,而是指占用同一片内存空间,完全是一样的。这点在解题的时候至关重要!!!!一旦找到了一个这样的节点,那么之后两个链表的节点对应着也就占用相同的内存空间,就无需判断了。这是因为由链表的性质决定的,node.next只有一个。

先上来代码:

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution
{
public ListNode getIntersectionNode(ListNode headA, ListNode headB)
{
if(headA==null||headB==null){
return null;
}
int lengthA=;
int lengthB=;
ListNode node1=headA;
ListNode node2=headB;
ListNode result=null;
while(node1!=null)
{
lengthA++;
node1=node1.next;
}
while(node2!=null)
{
lengthB++;
node2=node2.next;
}
node1=headA;
node2=headB;
while(lengthA>lengthB)
{
node1=node1.next;
lengthA--;
}
while(lengthA<lengthB)
{
node2=node2.next;
lengthB--;
}
//此时node1 node2已经指向了合适的位置,确保到尾节点的长度是一样的。
while(true)
{
if(node1==node2)//这里nowA==nowB意味着从该节点之后所有链表节点都是公用的,尤其要理解题意,这里的相交不只是指链表中的值相同,而是链表中的元素就是同一块内存空间,一旦找到了同一块内存,那么之后的链表也一定是同一块内存。
{
result=node1;
break;
}
if(node1==null||node2==null)
{
break;
}
node1=node1.next;
node2=node2.next;
}
return result;
}
}

算法分析:

1、寻找相交链表的起始节点,首先要判断好什么才意味着相交。

2、相交意味着从某一节点开始直至链表的结束,中间所有的节点都只有一个,也就是说从开始节点开始,两个链表就是一个链表了!

3、那么即使两个链表的长度不同,但两个链表右端一定是对齐的。所以首先我们要获取长度相同的两个链表段,他们的起始点到各自的终点长度一样,这是相交链表的基本要求。

4、所以,我们先获取两个链表各自的长度,接着把根据两个长度的大小关系把各自指针node1、node2指向合适的位置,确保头指针到尾节点的长度一样。

5、接下来,就是判断是否存在占用同一片内存空间的节点了。

6、进行迭代,如找到了这样的节点令result=node1(node2),并跳出迭代。或者已经迭代到了尾节点,也跳出迭代。否则node1后移一位,node2后移一位。

7、返回节点result,这个节点就是相交节点的入口。

LeetCode 160——相交链表(JAVA)的更多相关文章

  1. Java实现 LeetCode 160 相交链表

    160. 相交链表 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4, ...

  2. LeetCode 160 相交链表

    题目: 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], li ...

  3. LeetCode 160. 相交链表(Intersection of Two Linked Lists)

    题目描述 编写一个程序,找到两个单链表相交的起始节点. 例如,下面的两个链表: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 在节点 c1 开始相交. 注意: ...

  4. leetcode 160相交链表

    暴力解法当然可以遍历两个链表,不过time O(mn) space O(1)暂且不说, 方法一:双指针, time O(m+n),space O(1) 可以对比判断环形链表的快慢指针法. 这种方法构思 ...

  5. LeetCode 160. 相交链表 (找出两个链表的公共结点)

    题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/ 编写一个程序,找到两个单链表相交的起始节点. 如下面的两 ...

  6. Leetcode题目160.相交链表(简单)

    题目描述 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = ...

  7. 【LeetCode】160. 相交链表

    题目 输入两个链表,找出它们的第一个公共节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB ...

  8. [LeetCode题解]160. 相交链表 | 双指针 + 哈希表

    方法一:双指针 解题思路 假设链表存在相交时,headA 的长度为 a + c,headB 的长度为 b + c.如果把 headA 连上 headB,headB 连上 headB 的话,当遍历这两个 ...

  9. leetcood学习笔记-160*-相交链表

    题目描述: 方法一: class Solution(object): def getIntersectionNode(self, headA, headB): """ : ...

随机推荐

  1. app支付宝充值

    首先支付宝需要开通app 支付 然后登录支付宝 ,点击合作伙伴, 进入 开放平台,申请一个应用. 下载支付宝开放平台助手, 生成应用公钥,点击上传 设置进入之前申请的应用,支付宝自动生成支付宝公钥,设 ...

  2. MAC为Apache2服务器配置多个虚拟主机

    Mac 下自带的 Apache 配置 2016年01月25日 00:25:03 阅读数:1292 参考: http://www.cnblogs.com/snandy/archive/2012/11/1 ...

  3. 【VMWare】虚拟机启动遇到黑屏,在命令行窗口输入netsh winsock reset并不管用 重新启动客户机就好了

    现象:虚拟机启动后是莫名其妙的黑屏,而且它上面安装的MySql也无法访问了. 处置:上网百度方案,看到大多数网文推荐:“以管理员身份打开cmd,输入netsh winsock reset,然后重启机器 ...

  4. quartz 定时器时间表达式

    按顺序依次为 秒(~) 分钟(~) 小时(~) 天(月)(~,但是你需要考虑你月的天数) 月(~) 天(星期)(~ =SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT) .年份(-) ...

  5. 自定义vue-cli生成项目模板配置(1)

    最近在读<变量>,目前得到的认知之一:慢变量才是决定事物长期发展的因素. 打算自定义vue-cli的脚手架或者根据自己的需要设置项目模板的相关参数,很大程度与慢变量这个概念相关. 当然,我 ...

  6. Android 美团Robust热更新 使用入门

    Android热更新方案Robust 相信很多人都认识了解过 热修复.热更新.热补丁(对于这个技术也没有特别标准的一种叫法,下面我统一叫热更新),之后的一年里,各种热更新方案如雨后春笋般出现,比较耳熟 ...

  7. golang 故障模拟工具failpoint的使用

    测试是功能上线之前的重要环节. 测试过程中,要尽量覆盖各种场景.故障情况或异常情况下的场景测试,也是必不可少的. 如何模拟故障呢? 在FreeBSD 中, failpoints经常用来模拟故障. 在g ...

  8. CSS 优先级法则

    样式的优先级 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况. 一般情况下,优先级如下: (外部样式)External styl ...

  9. kotlin之包

    在kotlin中包的概念在表达方式上与Java完全一样,不过kotlin中的包和目录没有关系,kotlin包仅仅是为了引用文件中的资源而设计的. package loaderman.bar fun p ...

  10. 准确率(Precision)、召回率(Recall)以及综合评价指标(F1-Measure)

    在信息检索和自然语言处理中经常会使用这些参数,下面简单介绍如下: 准确率与召回率(Precision & Recall) 我们先看下面这张图来加深对概念的理解,然后再具体分析.其中,用P代表P ...