给你一个链表和一个特定值 x ,请你对链表进行分隔,使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入:head = 1->4->3->2->5->2, x = 3
输出:1->2->2->4->3->5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
第一种思路:
暴力解,线性扫描输入链表,然后维护两个新的链表,第一个链表按顺序储存所有小于x 的节点,第二个链表按顺序储存所有大于或等于x的节点。
维护完成后,把第二个链表的头接到第一个链表的尾部即可。
时间复杂度:O(N)
空间复杂度:O(N)
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
smaller_dummy_head = ListNode(-2)
larger_dummy_head = ListNode(-1)
p = head
ps, pl = smaller_dummy_head, larger_dummy_head
while p:
if p.val < x:
ps.next = ListNode(p.val)
ps = ps.next
else:
pl.next = ListNode(p.val)
pl = pl.next
p = p.next
ps.next = larger_dummy_head.next
return smaller_dummy_head.next
第二种思路:
原地算法,
首先找到第一个大于等于x的Node,以它和它的preNode之间的间隔作为分割点,将链表一分为二,前一半叫做first_tail, 后一半叫做second_head。
为啥要这么分呢,因为前一半链表已经排好序了,我们接下来要做的就是把后一半链表里的所有比 x 小的Node 拿出来,再按顺序插入到前一半链表的尾部。
时间复杂度:O(N)
空间复杂度:O(1)
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
if not head:
return head
dummy_head = ListNode(-1, head)
p = dummy_head
second_head = None
while p and p.next:
if p.next.val >= x:
first_tail = p
second_head = p.next
break
p = p.next
if not second_head:
return head
pre = second_head
p = second_head.next
while p:
nxt = p.next
if p.val < x:
# pull out Node p, and append it to the first tail
pre.next = p.next
first_tail.next = p
first_tail = first_tail.next
p.next = second_head
else:
pre = p
p = nxt
return dummy_head.next
def printLL(self, l):
res = []
p = l
while p:
res.append(p.val)
p = p.next
print(res)