2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2。请实现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null。【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。

福大大 答案2021-04-10:

1.获取head1和head2的第一个入环节点。

2.head1和head2环节点的3种情况。

2.1.如果head1和head2只有其中一个有环,直接返回false。

2.2.如果head1和head2都没环。双指针,见力扣【剑指 Offer 52. 两个链表的第一个公共节点】。

2.3.如果head1和head2都有环。精髓在这里。

2.3.1.head1和head2根据入环节点分别断成两个链表。

2.3.2.head1左部分和head2左部分,根据2.2步骤求交点。保存在ans中。

2.3.3.head1和head2左右部分分别合并。

2.3.如果ans为空,需要循环判断head1的入环节点,如果循环了一圈都没找到head2中的入环节点,ans肯定为空;如果找到了,ans为head1的入环节点。

3.返回ans。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
head1 := &ListNode{Val: 1}
head1.Next = &ListNode{Val: 2}
head1.Next.Next = &ListNode{Val: 3}
head1.Next.Next.Next = &ListNode{Val: 4}
head1.Next.Next.Next.Next = &ListNode{Val: 5}
head1.Next.Next.Next.Next.Next = &ListNode{Val: 6}
head1.Next.Next.Next.Next.Next.Next = head1.Next.Next head2 := &ListNode{Val: 7}
head2.Next = &ListNode{Val: 8}
head2.Next.Next = head1.Next.Next.Next.Next ret := getIntersectionNode(head1, head2)
fmt.Println(ret)
} //Definition for singly-linked list.
type ListNode struct {
Val int
Next *ListNode
} func getIntersectionNode(head1, head2 *ListNode) *ListNode {
if head1 == nil || head2 == nil {
return nil
}
loop1 := GetLoopNode(head1)
loop2 := GetLoopNode(head2)
if loop1 == nil && loop2 == nil {
return NoLoop(head1, head2)
}
if loop1 != nil && loop2 != nil {
return BothLoop(head1, loop1, head2, loop2)
}
return nil
} //获取入环节点
func GetLoopNode(head *ListNode) *ListNode {
if head.Next == nil || head.Next.Next == nil {
return nil
}
slow := head.Next
fast := head.Next.Next
for slow != fast {
if fast.Next == nil || fast.Next.Next == nil {
return nil
}
fast = fast.Next.Next
slow = slow.Next
}
fast = head
for slow != fast {
slow = slow.Next
fast = fast.Next
}
return slow } //没有入环节点
func NoLoop(head1 *ListNode, head2 *ListNode) *ListNode {
cur1 := head1
cur2 := head2
for i := 0; i < 3; i++ {
for cur1 != nil && cur2 != nil {
if cur1 == cur2 {
return cur1
}
cur1 = cur1.Next
cur2 = cur2.Next
}
if cur1 == nil {
cur1 = head2
} else if cur2 == nil {
cur2 = head1
}
}
return nil
} //有入环节点
func BothLoop(head1 *ListNode, loop1 *ListNode, head2 *ListNode, loop2 *ListNode) *ListNode {
loop1Next := loop1.Next
loop2Next := loop2.Next
//head1和head2根据入环节点分别断成两个链表。
loop1.Next = nil
loop2.Next = nil
//head1左部分和head2左部分,根据2.2步骤求交点。保存在ans中。
ans := NoLoop(head1, head2)
//head1和head2左右部分分别合并。
loop1.Next = loop1Next
loop2.Next = loop2Next
//如果ans为空,需要循环判断head1的入环节点,如果循环了一圈都没找到head2中的入环节点,ans肯定为空;如果找到了,ans为head1的入环节点。
if ans == nil {
loop1Copy := loop1.Next
for loop1Copy != loop1 {
if loop1Copy == loop2 {
ans = loop1
break
}
loop1Copy = loop1Copy.Next
}
}
//返回ans。
return ans
}

执行结果如下:


左神java代码

评论

2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2。请实现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null。【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。的更多相关文章

  1. 有两个指针pa,pb分别指向有两个数,a,b,请写一个函数交换两个指针的指向,也就是让pa指向b,让pb指向a

    题目:有两个指针pa,pb分别指向有两个数,a,b,请写一个函数交换两个指针的指向,也就是让pa指向b,让pb指向a,具体实现如下: #include<stdlib.h> #include ...

  2. 有两个数a,b,请写一个函数交换a,b

    题目:有两个数a,b,请写一个函数交换a,b,具体实现如下: #include<stdlib.h> #include<stdio.h> int swap(int * pA, i ...

  3. 判断一个链表是否为回文结构 【题目】 给定一个链表的头节点head,请判断该链表是否为回 文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。 15->6->15,返回true。 1->2->3,返回false。 进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 度达到O(1)。

    方式1:借助栈 空间辅助度是O(N) 方式2: 借助栈 空间复杂度是 O(n/2).只存后半个链表 方式3: 反转后半个链表  最后再反转回来 package my_basic.class_3; im ...

  4. 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  5. 打印两个有序链表的公共部分 【题目】 给定两个有序链表的头指针head1和head2,打印两个 链表的公共部分

    简单题 package my_basic.class_3; public class Code_10_PrintCommonPart { public static class Node{ int v ...

  6. 请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程 ax^2+bx+c=0ax 2 +bx+c=0 的两个解。

    #!/usr/bin/python # 导入math包 import math def quadratic(a, b, c): if not isinstance(a, (int, float))an ...

  7. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  8. opencv局限:cv::FileStorage读取中,xml文件的第一层节点不能超过4个

    今天测试发现一个问题,cv::FileStorage读取中,xml文件的第一层节点不能超过4个. <?xml version="1.0"?> <opencv_st ...

  9. python 练习题:定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程ax^2+bx+c=0的两个解

    请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程 ax^2+bx+c=0的两个解. 提示: 一元二次方程的求根公式为: x1 = (-b + math.sqrt((b ...

  10. 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用

    一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] ...

随机推荐

  1. C#重点语法——反射

    ------------恢复内容开始------------ 一.含义 反射是指访问,检测或修改程序代码本身状态或行为的一种技术. 举例: 官方代码继承了IReflect ------------恢复 ...

  2. Markdown操作方法

    Markdown学习 标题 三级标题 四级标题 字体 原本 hello,world! 斜体 hello,world! 加粗 hello,world! 斜体加粗 hello,world! 删除 hell ...

  3. Hyperf安装

    转载网址: https://www.cnblogs.com/lyc94620/p/12821723.html

  4. 痞子衡嵌入式:我当选了2019年度官方论坛i.MXRT板块的顶级贡献者

    痞子衡桌上有一个联邦快递公司件,放了近一个月了,是同事代领的,痞子衡一直没有拆开.今天心血来潮,决定拆开瞧一瞧,这一拆就拆出了一天的好心情. 原来快递里面是一件i.MXRT产品纪念T-shirt,还有 ...

  5. Typora编辑区域空白过大问题

    参考博客:https://blog.csdn.net/m0_55485287/article/details/115207178 在哪个文件编辑? 1.找到使用的主题,打开主题文件夹 2.找到对应的c ...

  6. 跳出思维的“盒子”,聊聊 RTE 应用创新大赛的那些作品

    由声网Agora 与环信联合主办的"RTE 2021 编程挑战赛"已圆满落幕.在今年的大赛中,来自行业中不同领域的专家参与了决赛评选,包括 Linux 中国技术社区技术负责人 白宦 ...

  7. graphviz 简单入门

    上一位负责画图的选手 CS Academy 由于不明原因暂时不能继续工作,所以本俱乐部招收了新选手 graphviz. 在 Linux 上,你可以这么下载: sudo apt install grap ...

  8. 一文学会Flex布局

    参考: <CSS权威指南>(第四版) flex布局教程-语法篇-阮一峰 1.Flex布局是什么 FlexBox,弹性盒布局,顾名思义,就是元素具有弹性,能根据可用空间大小增减尺寸. 2.基 ...

  9. RPC 与 Restful 的区别

    PRC 是一种技术的代名词,HTTP 是一种协议,RPC 可以通过 HTTP 来实现,也可以通过 Socket 自己实现一套协议来实现.所以谈论为什么用 RPC 不用 HTTP 是无意义的.但我们习惯 ...

  10. Flutter中如何取消任务

    前言 在开发过程中,取消需求是很常见的,但很容易被忽略.然而,取消需求的好处也很大.例如,在页面中会发送很多请求.如果页面被切走并处于不可见状态,就需要取消未完成的请求任务.如果未及时取消,则可能会导 ...