写点什么

判断两个链表是否合并

用户头像
Acker飏
关注
发布于: 2020 年 07 月 30 日

有两个单向链表(链表长度分别为 m,n),这两个单向链表有可能在某个元素合并,如下图所示的这样,也可能不合并。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并?如果合并,找到合并的元素,也就是图中的 x 元素。



思路:将两个链表每个节点向右对齐,以短的那个链的第一个节点为准,将下标指向同一个位置,向后遍历遇到相同的节点即为合并的元素。

其时间复杂度O(n),空间复杂度O(1)



核心代码:

fun <T> getCombinedNode(firstList: LinkedNode<T>, secondList: LinkedNode<T>): LinkedNode<T>? {
// 获得两个链表的长度
val fistLength = firstList.length
val secondLength = secondList.length
// 如果有一个链表长度为0,则直接判定为未合并
if (fistLength == 0 || secondLength == 0) return null
// 确定长链和短链
var shortNode = if (fistLength <= secondLength) firstList else secondList
var longNode = if (fistLength > secondLength) firstList else secondList
// 将两个链表向右对齐,短链下标指向第一个位置,长链指向对齐后同一位置
repeat((fistLength - secondLength).absoluteValue) {
longNode = longNode.next!!
}
// 如果第一个元素相同则返回当前节点
if (shortNode == longNode) return shortNode
// 将下标逐个后移直到找到相同的节点
while(shortNode.next != null) {
shortNode = shortNode.next!!
longNode = longNode.next!!
if (shortNode == longNode) return shortNode
}
return null
}
class LinkedNode<T>(var value: T) {
var next: LinkedNode<T>? = null
override fun toString() = "$value[$value -> ${next?.value ?: "null"}]"
}

测试:

fun main() {
val a = LinkedNode("a")
val b = LinkedNode("b")
val d = LinkedNode("d")
val e = LinkedNode("e")
val f = LinkedNode("f")
val x = LinkedNode("x")
val y = LinkedNode("y")
val z = LinkedNode("z")
a.next = b
b.next = x
x.next = y
y.next = z
d.next = e
e.next = f
f.next = x
x.next = y
y.next = z
val firstList = a
val secondList = d
val combinedNode = getCombinedNode(firstList, secondList)
if (combinedNode == null) println("两个链表没有合并")
else println(
"两个链表在 $combinedNode 处合并\n" +
"Index分别为[${firstList.indexOf(combinedNode)}],[${secondList.indexOf(combinedNode)}]"
)
}

输出:

两个链表在 x[x -> y] 处合并
Index分别为[2],[3]

Process finished with exit code 0



发布于: 2020 年 07 月 30 日阅读数: 58
用户头像

Acker飏

关注

还未添加个人签名 2018.05.03 加入

还未添加个人简介

评论

发布
暂无评论
判断两个链表是否合并