# [86. Partition List](https://leetcode.com/problems/partition-list/) ## 题目 Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. **Example**: ``` Input: head = 1->4->3->2->5->2, x = 3 Output: 1->2->2->4->3->5 ``` ## 题目大意 给定一个数 x,比 x 大或等于的数字都要排列在比 x 小的数字后面,并且相对位置不能发生变化。由于相对位置不能发生变化,所以不能用类似冒泡排序的思想。 ## 解题思路 这道题最简单的做法是构造双向链表,不过时间复杂度是 O(n^2)。 (以下描述定义,大于等于 x 的都属于比 x 大) 更优的方法是新构造 2 个链表,一个链表专门存储比 x 小的结点,另一个专门存储比 x 大的结点。在原链表头部开始扫描一边,依次把这两类点归类到 2 个新建链表中,有点入栈的意思。由于是从头开始扫描的原链表,所以原链表中的原有顺序会依旧被保存下来。最后 2 个新链表里面会存储好各自的结果,把这两个链表,比 x 小的链表拼接到 比 x 大的链表的前面,就能得到最后的答案了。 ## 代码 ```go package leetcode /** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ // 解法一 单链表 func partition(head *ListNode, x int) *ListNode { beforeHead := &ListNode{Val: 0, Next: nil} before := beforeHead afterHead := &ListNode{Val: 0, Next: nil} after := afterHead for head != nil { if head.Val < x { before.Next = head before = before.Next } else { after.Next = head after = after.Next } head = head.Next } after.Next = nil before.Next = afterHead.Next return beforeHead.Next } // DoublyListNode define type DoublyListNode struct { Val int Prev *DoublyListNode Next *DoublyListNode } // 解法二 双链表 func partition1(head *ListNode, x int) *ListNode { if head == nil || head.Next == nil { return head } DLNHead := genDoublyListNode(head) cur := DLNHead for cur != nil { if cur.Val < x { tmp := &DoublyListNode{Val: cur.Val, Prev: nil, Next: nil} compareNode := cur for compareNode.Prev != nil { if compareNode.Val >= x && compareNode.Prev.Val < x { break } compareNode = compareNode.Prev } if compareNode == DLNHead { if compareNode.Val < x { cur = cur.Next continue } else { tmp.Next = DLNHead DLNHead.Prev = tmp DLNHead = tmp } } else { tmp.Next = compareNode tmp.Prev = compareNode.Prev compareNode.Prev.Next = tmp compareNode.Prev = tmp } deleteNode := cur if cur.Prev != nil { deleteNode.Prev.Next = deleteNode.Next } if cur.Next != nil { deleteNode.Next.Prev = deleteNode.Prev } } cur = cur.Next } return genListNode(DLNHead) } func genDoublyListNode(head *ListNode) *DoublyListNode { cur := head.Next DLNHead := &DoublyListNode{Val: head.Val, Prev: nil, Next: nil} curDLN := DLNHead for cur != nil { tmp := &DoublyListNode{Val: cur.Val, Prev: curDLN, Next: nil} curDLN.Next = tmp curDLN = tmp cur = cur.Next } return DLNHead } func genListNode(head *DoublyListNode) *ListNode { cur := head.Next LNHead := &ListNode{Val: head.Val, Next: nil} curLN := LNHead for cur != nil { tmp := &ListNode{Val: cur.Val, Next: nil} curLN.Next = tmp curLN = tmp cur = cur.Next } return LNHead } ```