题目描述
刚开始接触这个题目时,想到用两种方法。一种是使用两个列表来完成,一种是使用一个列表来完成。
方法一:双链表+双指针
构建结点的部分就不多说了,前面两个博客都有说到。详细讲讲是如何实现分隔的。
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
'''方法一:两个指针,两个链表'''
daummy = ListNode(-1)
daummy2 = ListNode(-1)
i = daummy
p,q = daummy, daummy2 # p用来插入小于x的值,q用来插入比x大的值
# q = p.next
k = head
# for i in head: # 注意,这里的head是链表,所以不能迭代
# 氛围两个链表记录,最后再整合起来
while k:
node = ListNode(k.val)
if node.val < x:
node.next = p.next
p.next = node
p = p.next
else:
node.next = q.next
q.next = node
q = q.next
k = k.next
p.next = daummy2.next
return daummy.next
首先构建两个哑指针,daummy是用来存放小于x的值的链表,daummy2是用来存放大于等于x的值的链表。从目标链表中读取一个指针,判断它是属于daummy和daummy2那个范畴,然后在一次添加到对应的链表即可。请注意,这里从目的链表读取数据的时候,我是重新创建了一个结点,创建时是默认结点的next=None,因此避免了成环的可能性。
下面是完整代码;
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class LinkList(object):
def __init__(self):
self.head = None # 先定义一个空的头节点
def linknode(self, data):
head = ListNode(data[0])
p,q = head, head
for i in data[1:]: # 流程:1、创建结点 2、指针的next指向结点 3、指针指向下一个结点
node = ListNode(i)
p.next = node
p = p.next
return q
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
'''方法一:两个指针,两个链表'''
daummy = ListNode(-1)
daummy2 = ListNode(-1)
i = daummy
p,q = daummy, daummy2 # p用来插入小于x的值,q用来插入比x大的值
# q = p.next
k = head
# for i in head: # 注意,这里的head是链表,所以不能迭代
# 氛围两个链表记录,最后再整合起来
while k:
node = ListNode(k.val)
if node.val < x:
node.next = p.next
p.next = node
p = p.next
else:
node.next = q.next
q.next = node
q = q.next
k = k.next
p.next = daummy2.next
return daummy.next
if __name__ == '__main__':
head = [1, 4, 3, 2, 5, 2]
x = 3
createlist = LinkList()
list = createlist.linknode(head)
aa = Solution()
result = aa.partition(list, x)
# a = 1
方法二:单链表+双指针+队列
在实现这个方法中,我发现在插入比x大的值的时候,我无法明确的插入指定的位置。所以查看题解,看到一位作者——ThisIsT用队列的先进先出的特性来解决这个问题。觉得很新颖!
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
'''方法二:辅助头节点+双指针+队列'''
dummy = ListNode(-1)
pre, dummy.next, cur = dummy, head, head
helper = []
if not head: return None
while cur.next:
if cur.val<x:
cur = cur.next
pre=pre.next
else:
pre.next = cur.next
cur.next = None
helper.append(cur)
cur = pre.next
if cur.val>=x:
pre.next = None
helper.append(cur)
cur = pre
while helper:
node = helper.pop(0)
cur.next = node
cur = cur.next
return dummy.next
# 作者:ThisIsT
# 链接:https: // leetcode.cn / problems / partition - list /
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个方法加强了我对于队列的应用理解,之前我对于队列的应用只限于存储数值数据对象,没有想过还可以存储结点数据对象,很新奇!完整代码如下:
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class LinkList(object):
def __init__(self):
self.head = None # 先定义一个空的头节点
def linknode(self, data):
head = ListNode(data[0])
p,q = head, head
for i in data[1:]: # 流程:1、创建结点 2、指针的next指向结点 3、指针指向下一个结点
node = ListNode(i)
p.next = node
p = p.next
return q
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
'''方法二:辅助头节点+双指针+队列'''
dummy = ListNode(-1)
pre, dummy.next, cur = dummy, head, head
helper = []
if not head: return None
while cur.next:
if cur.val<x:
cur = cur.next
pre=pre.next
else:
pre.next = cur.next
cur.next = None
helper.append(cur)
cur = pre.next
if cur.val>=x:
pre.next = None
helper.append(cur)
cur = pre
while helper:
node = helper.pop(0)
cur.next = node
cur = cur.next
return dummy.next
# 作者:ThisIsT
# 链接:https: // leetcode.cn / problems / partition - list /
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
if __name__ == '__main__':
head = [1, 4, 3, 2, 5, 2]
x = 3
createlist = LinkList()
list = createlist.linknode(head)
aa = Solution()
result = aa.partition(list, x)
# a = 1