86. 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 大的链表的前面,就能得到最后的答案了。
代码 #
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
}