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. LaTeX in 24 Hours - 书籍信息

    书籍信息 书名: LaTex in 24 Hours: A Practical Guide for Scientific Writing 作者: Dilip Datta 出版日期: 2017 ISBN ...

  2. mimikatz和procdump的密码抓取

    mimikatz mimikatz功能很强大,主要使用就是提取明文密码.哈希.PIN码和Kerberos凭证. 常用的只有两条命令: 注意:运行时使用管理员身份运行 privilege::debug ...

  3. 写.jsp项目有感

    本次练习了一个简单的登录界面 我觉得在写这种类型的界面的时候,需要将各个需求分开,就以这次的登录界面为例展开说说 1.登录界面 输入框的居中问题.登录按钮的跳转问题.验证码图片的随机问题.快速注册的跳 ...

  4. PicGo + Gitee(码云)实现markdown图床 (转载)

    https://zhuanlan.zhihu.com/p/102594554 备忘录 我配置图床的时候参考的是这篇文章.我暂时使用的是这种方案. 因为考虑到有的文章要多平台发布,我建议你选择markd ...

  5. Go - 高并发抢到红包实现

    // utils.gopackage mainimport ( "fmt" "math/rand" "sync" "time&qu ...

  6. go简易tcp/udp连接测试工具

    package main import ( "fmt" "io" "log" "net" "os" ...

  7. node-sass与node版本对照图

  8. react之点语法(利用函数组件)

    index.js import React, { Component } from 'react' import MyCom from './MyCom'; export default class ...

  9. PyQt5学习 (2)--QWidget(上)

    描述:   1.所有可视控件的基类   2.是一个最简单的空白控件   3.控件时用户界面的最小元素:接收各种事件.绘制在桌面上,展示给用户看   4.每个控件都是矩形的,它们按Z轴顺序排序   5. ...

  10. Ubuntu2204部署容器引擎Containerd

    为什么使用containerd? 使用containerd的原因主要有两点吧,第一个是docker在k8s1.24以后不再支持,如果需要在k8s中继续使用docker作为容器引擎,我们需要额外部署cr ...