LeetCode86 分隔链表

34 阅读1分钟

leetcode.cn/problems/pa…

image.png

解法一:拆分链表再拼接

我们可以把原链表分成两个小链表,一个链表中的元素大小都小于 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 新节点来组成新链表的话,那么断开节点和原链表之间的链接可能是必要的,否则两条新链表可能由于原来的节点指向关系,导致有关联 image.png