有环链表的处理

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 【5月更文挑战第7天】该文介绍了链表环的检测和处理方法。使用快慢指针可判断链表是否存在环,相遇点距离等于环入口距离。环的长度可通过相遇时慢指针的步长计算。若两链表相交,它们的尾节点相同。

简介

有环链表,也就是一个链表中至少有一个环。

image.png

双向链的每个节点的prev指向上一个节点,next指针指向下一个节点。

1 一个链表,判断链表中是否有环。

思路: 快慢指针,设定两个指针,fast 步长为2,slow 步长为1,遍历,
从同一点出发,如果两个指针相遇,那么表示这个链表有环。
如果没有环,那么fast 先达到 NULL

快慢指针相遇时的循环次数等于环的长度。

如何找出 环链表的入口

    思路: 快慢指针相遇点 到环入口的距离 = 链表起始点到环 入口的距离

如何求解环的长度

    思路:当两个指针相遇Z时,此时slow走过的路径为 a + b, fast走过的路径为 a+b+c+b, 因为fast步长为 slow的两边,所以 2(a+b)=a+b+c+b

所以 a = c, 环的长度为 b + c,也就是 a+b,即slow走过的步长如何判断两个链表是否相交

    思路: 如果两个链表相交,那么这两个链表尾节点 一定相同,直接判断尾节点是否相同即可,

2 例子:环形链表可以拆分为两个Y链表。

环形链表用例: pos 表示 链表尾部节点 执行该链表的 哪一个节点:

        输入:
        [3,2,0,-4]    pos = 1  # 表示1个环 -4 与 2相 链
            |____|

        输出:
        tail connects to node index 1

        输入:
            [1, 3, 4]  pos =0   #  表示 4 与 1 首尾相连
            |_____|
        输出:
            tail connects to node index 0

        输入:
            [1, 2]  pos = 0  # 表示 2 与 1 连
            |__|
        输出:
            tail connects to node index 0

        输入:
            [-1]
            -1  # 表示没有 环
        输出:
            null

3 实现

我们使用双向链表实现环形链接。首先定义链表的每个节点

   type Node struct {
        Number int
        Prev   *Node
        Next   *Node
}

  type Doublist struct {
        Lens int
        Head *Node
        Tail *Node
}

func MakeDlist() *Doublist {
        return &Doublist{}
}

实现对节点的有序放入

func (th *Doublist) Pushback(n *Node) bool {
        if n == nil {
                return false
        }
        currentNode := th.Head
        if currentNode == nil {

                return th.NewNodeList(n)
        } else {
                inDex, insertNode := th.Lesseq(n)
                if inDex == 0 {
                        return th.PushHead(n)
                } else if inDex == (th.Lens-1) && insertNode == nil {
                        return th.Append(n)
                } 

                n.Next = insertNode
                n.Prev = insertNode.Prev
                if insertNode.Prev != nil {
                        insertNode.Prev.Next = n
                }

                insertNode.Prev = n
                th.Lens += 1
                return true
        }
}

显示链表的值

func (th *Doublist) Display() {

        node := th.Head
        t := 0
        Logg.Println(node.Number)
        for node != nil {
                t += 1
                if t >= th.Lens {
                        break
                }

                node = node.Next
                Logg.Println(node.Number)
        }

        Logg.Println("length:", th.Lens)
}

然后定义环形链表

   type CycleLinked struct {
        Size  int
        Items *Doublist
}

链表缓存通道

type MyChan struct {
        Read  <-chan *Node
        Input chan<- *Node
}

添加多个节点到链表

func (cl *CycleLinked) SetItems(n int) *CycleLinked {
        if n <= cl.Size {
                cl.Items = MakeDlist()
                for i := 0; i < n; i++ {
                        cl.Items.Pushback(&Node{Number: i})
                }
        }

        return cl

}

使用有环链表,创建 空链表,填入数字

        tLinked := MakeEmptyLinked(8)

        numberC := tLinked.SetItems(tLinked.Size)

        cNode := numberC.Items.Head
        for cNode != nil {
                Logg.Printf("%+v\n", cNode)
                cNode = cNode.Next
        }
}

3 小结

该文本为工具使用解说。使用双指针法来判断一个单向链表是否存在环,而最后判断环的位置时,则需要利用快慢指针相遇后的特性来定义第三个指针,从而找到入口位置,其实找到环的位置代码不难,关键是推理的过程需要去理解。

源码地址:

 https://github.com/hahamx/utools/blob/main/utils/circled/main.go
目录
相关文章
【腾讯】环形链表(证明有环)
【腾讯】环形链表(证明有环)
|
11月前
|
测试技术
【面试必刷TOP101】合并k个已排序的链表 & 判断链表中是否有环
【面试必刷TOP101】合并k个已排序的链表 & 判断链表中是否有环
55 0
|
3月前
|
算法
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
|
11月前
|
存储 索引
判断环形链表是否有环??返回环形链表的入口点!!
判断环形链表是否有环??返回环形链表的入口点!!
36 1
|
9月前
|
机器学习/深度学习 存储 缓存
有环链表环的问题
有环链表环的问题
|
算法
大厂面试经典单链表例题(创建有序单链表,逆置单链表,判断链表是否有环,取链表中间节点)(含核心代码与解析)
大厂面试经典单链表例题(创建有序单链表,逆置单链表,判断链表是否有环,取链表中间节点)(含核心代码与解析)
牛客hot100--BM6---判断链表中是否有环(简单难度)
牛客hot100--BM6---判断链表中是否有环(简单难度)
127 0
牛客hot100--BM6---判断链表中是否有环(简单难度)
|
算法 索引
【切图仔的算法修炼之旅】LeetCode141:判断链表是否有环
【切图仔的算法修炼之旅】LeetCode141:判断链表是否有环
95 0
【切图仔的算法修炼之旅】LeetCode141:判断链表是否有环
|
算法
【牛客刷题-算法】NC4 判断链表中是否有环
【牛客刷题-算法】NC4 判断链表中是否有环
99 0
【牛客刷题-算法】NC4 判断链表中是否有环