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

2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2。请实现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null。【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。的更多相关文章
- 有两个指针pa,pb分别指向有两个数,a,b,请写一个函数交换两个指针的指向,也就是让pa指向b,让pb指向a
题目:有两个指针pa,pb分别指向有两个数,a,b,请写一个函数交换两个指针的指向,也就是让pa指向b,让pb指向a,具体实现如下: #include<stdlib.h> #include ...
- 有两个数a,b,请写一个函数交换a,b
题目:有两个数a,b,请写一个函数交换a,b,具体实现如下: #include<stdlib.h> #include<stdio.h> int swap(int * pA, i ...
- 判断一个链表是否为回文结构 【题目】 给定一个链表的头节点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 ...
- 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- 打印两个有序链表的公共部分 【题目】 给定两个有序链表的头指针head1和head2,打印两个 链表的公共部分
简单题 package my_basic.class_3; public class Code_10_PrintCommonPart { public static class Node{ int v ...
- 请定义一个函数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 ...
- 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- opencv局限:cv::FileStorage读取中,xml文件的第一层节点不能超过4个
今天测试发现一个问题,cv::FileStorage读取中,xml文件的第一层节点不能超过4个. <?xml version="1.0"?> <opencv_st ...
- 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 ...
- 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用
一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] ...
随机推荐
- 删除Mac版word上方的Mathtype
原因 Mac升级到macOS Catalina v10.15.3发现mathtype用不了, Mathtype官网说目前暂时不支持这个版本的系统. 现在尴尬的是, mathtype删除了, 但一不小心 ...
- 三天吃透RabbitMQ面试八股文
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
- 初识C 语言
程序语言 C语言是目前极为流行的一种计算机程序设计语言,它既具有高级语言的功能,又具有汇编语言的一些特性.支持ANSIC. C语言的特点:通用性及易写易读 是一种结构化程序设计语言 具有良好的可移 ...
- DSC:数仓SQL脚本迁移的神奇工具
摘要:本文介绍的DSC工具是针对数据库切换时面临的迁移任务而开发的免安装命令行工具.目的是提供简单.快速.可靠的SQL脚本迁移服务. 本文分享自华为云社区<GaussDB(DWS)DSC工具系列 ...
- 操作系统 && C语言 每日学习记录(day1 ~ day8) 已寄
现在正式工作了,发现之前学的东西,很多一知半解,不通透,准备再好好系统学一些计算机原理的东西,每天学一学,在这里记录一下. 规划(7.17开始): 同学分享了个超级好的操作系统课程,每天看个一节:ht ...
- NET 8 预览版 2 亮点是Blazor
.NET 团队在2023年3月14日发布了.NET 8预览版2,博客文章地址:https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-pre ...
- Salesforce LWC学习(十二) Dependence Picklist实现
本篇可参看: Salesforce LWC学习(六) @salesforce & lightning/ui*Api Reference salesforce零基础学习(八十七)Apex 中Pi ...
- springboot格式化timestamp时间
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
- 写书写到一半,强迫症发作跑去给HotChocolate修bug
前言 这是写作<C#与.NET6 开发从入门到实践>时的小故事,作为本书正式上市的宣传,在此分享给大家. 正文 .NET目前有两个比较成熟的GraphQL框架,其中一个是HotChocol ...
- odoo 开发入门教程系列-准备一些操作(Action)?
准备一些操作(Action)? 到目前为止,我们主要通过声明字段和视图来构建模块.在任何真实的业务场景中,我们都希望将一些业务逻辑链接到操作按钮.在我们的房地产示例中,我们希望能够: 取消或将房产设置 ...