题目描述:
给出一个链表和一个值x,要求将链表中所有小于x的值放到左边,所有大于x的值放到右边,并且原链表的节点顺序不能变?
例如:
例如:1->5->3->2->4->2,给定 x=3 ,则返回为 1->2->2->5->3->4
思路:
对于这道题目我们要先处理左边即小于X的节点,在处理右边即大于X的节点,最后在将两边左右链接起来。
思考
我们如何处理左边,如何处理右边,处理完后如何在链接起来
1)首先将题目进行简化:
给出一个链表和一个X值,要求只保留链表中所有小于X的值原链表的节点顺序不能变
例如:例如:1->5->3->2->4->2,给定 x=3 ,则返回为 1->2->2
只要采用尾插法,遍历链表将小于X的值得节点接入新的链表即可
代码
func p_getLeftList(_ head: ListNode?,_ x: Int) -> ListNode? {
let dummy = ListNode.init(val: 0)
var per = dummy , node = head
while node != nil {
if node!.val < x{
per.next = node
per = node!
}
node = node!.next
}
//防止构成环
per.next = nil
return dummy.next
}
验证
@objc func getLeftList()
{
let one = ListNode.init(val: 1)
let two = ListNode.init(val: 5)
let three = ListNode.init(val: 3)
let four = ListNode.init(val: 2)
let five = ListNode.init(val: 4)
let six = ListNode.init(val: 2)
one.next = two
two.next = three
three.next = four
four.next = five
five.next = six
let result = self.p_getLeftList(one, 3)
var dummy = result
while dummy != nil {
print("node val: \(dummy!.val)")
dummy = dummy?.next
}
}
现在解决了左边,右边也是同样处理,接着只要让左边的尾结点指向右边的头节点即可
答案代码
func p_partition(_ head: ListNode?,_ x: Int) -> ListNode? {
//引入Dummy 节点
let prevDummy = ListNode.init(val: 0),postDummy = ListNode.init(val: 0)
var prev = prevDummy, post = postDummy
var node = head
//用尾插法处理左边和右边
while node != nil {
if node!.val < x {
prev.next = node
prev = node!
}else{
post.next = node
post = node!
}
node = node!.next
}
//防止循环引用
post.next = nil
//左右拼接
prev.next = postDummy.next
return prevDummy.next
}
测试:
func partition() {
let one = ListNode.init(val: 1)
let two = ListNode.init(val: 5)
let three = ListNode.init(val: 3)
let four = ListNode.init(val: 2)
let five = ListNode.init(val: 4)
let six = ListNode.init(val: 2)
one.next = two
two.next = three
three.next = four
four.next = five
five.next = six
let result = self.p_partition(one, 3)
var dummy = result
while dummy != nil {
print("node val: \(dummy!.val)")
dummy = dummy?.next
}
}
注意:
这里的 post.next = nil 是为了防止链表循环指向构成环,这时必须的