解法一:拆分链表再拼接
我们可以把原链表分成两个小链表,一个链表中的元素大小都小于 x,另一个链表中的元素都大于等于 x,最后再把这两条链表接到一起
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func partition(head *ListNode, x int) *ListNode {
if head == nil || head.Next == nil{
return head
}
// 注意:头节点的值大小不确定,因此一开始不能确认接在哪一条链上,不能初始化Next=head
dummy1 := &ListNode{ // 存放小于 x 的链表的虚拟头结点
Val : -201,
}
dummy2 := &ListNode{ // 存放大于等于 x 的链表的虚拟头结点
Val: -201,
}
// 将一个链表分解成两个链表
p1, p2 := dummy1, dummy2
cur := head
for cur != nil{
if cur.Val < x{
p1.Next = cur
p1 = p1.Next
}else{
p2.Next = cur
p2 = p2.Next
}
nxt := cur.Next
// 断开原链表中的每个节点的 next 指针,避免新链表成环
cur.Next = nil
cur = nxt
}
// 最后再把这两条链表接到一起
p1.Next = dummy2.Next
return dummy1.Next
}
为什么遍历过程中,要断开原链表中的每个节点的 next 指针?
如果我们需要把原链表的节点接到新链表上,而不是 new 新节点来组成新链表的话,那么断开节点和原链表之间的链接可能是必要的,否则两条新链表可能由于原来的节点指向关系,导致有关联