一、反转链表1
反转一个链表,将链表当中的第m个位置到第n个位置进行反转,同样的要求:在链表本身去做
例如:下图所示,要将2-4之间的节点进行一个反转
那思路跟上一篇文章的第5题思路很像,先将指针挪到准备反转的节点处,然后准备三个指针,pre_pointer,current_pointer,next_pointer,创建一个pre_pointer,next是我们的1节点,然后将pre_pointer走一步,到达节点1的位置,current_pointer就是pre_pointer.next,next_pointer 是current_pointer的next,current_pointer.next指向result,result移动到目前的current_pointer , current_pointer移动到next_pointer的位置上,依次向后,当遍历完成之后,current_pointer会指向节点9的位置,这个时候,将pre的next的next与翻转之后剩下的节点进行连接,pre的next指向我们翻转回来的第一个节点就可以了
上代码:
def reverse_LinkedList_m_to_n(node, start, end):
'''
:param node: 传入的链表头部节点
:param start: 反转的起始位置
:param end: 反转的结束位置
:return: 反转后的完整链表
'''
dummyNode = Node(0) # 创建一个哨兵节点
dummyNode.next = node
preNode = dummyNode
# 先用preNode这个指针移动到链表要开始反转的起始位置
# 到第2个节点,需要移动一次,即可之后的同理
for move in range(start - 1):
preNode = preNode.next
result = None
currentNode = preNode.next # 确定currentNode的位置
# 开始准备反转,移动的次数是end - start + 1次
for move in range(end - start + 1):
nextNode = currentNode.next
currentNode.next = result
result = currentNode
currentNode = nextNode
# 移动结束之后开始连接
preNode.next.next = currentNode
preNode.next = result
# 反转之后返回哨兵节点next后面的内容
return dummyNode.next
n1 = Node(1)
n2 = Node(3)
n3 = Node(5)
n4 = Node(7)
n5 = Node(9)
n1.next, n2.next, n3.next, n4.next = n2, n3, n4, n5
resList = reverse_LinkedList_m_to_n(n1, 2, 4)
L1 = LinkedList()
L1.head.next = resList
L1.print_linkedList()
resList = reverse_LinkedList_m_to_n(n1, 1, 3)
L2 = LinkedList()
L2.head.next = resList
L2.print_linkedList()
二、反转链表2
在一个链表当中交换两个相邻节点的值
思路:
还是准备哨兵节点,用来返回整个转换后的链表,用一个current节点用来进行移动,在进行交换的时候准备两个指针,一个pointer1一个pointer2,分别对应奇偶位的节点,向后移动的时候将pointer2的next指向pointer1,pointer1移动到pointer2的节点后面,然后将courrent向后移动两位,继续刚才的操作
上代码:
# swap LinkedList node
def swap_LinkedList(node):
dummyNode = current = Node(0)
current.next = node
while current.next != None and current.next.next != None:
# 创建两个指针用来专门做交换
pointer1 = current.next
pointer2 = current.next.next
current.next = pointer2
pointer1.next = pointer2.next
pointer2.next = pointer1
current = current.next.next
return dummyNode.next
n1 = Node(1)
n2 = Node(3)
n3 = Node(5)
n4 = Node(7)
n5 = Node(9)
n1.next, n2.next, n3.next, n4.next = n2, n3, n4, n5
L1_before = LinkedList()
L1_before.head.next = n1
L1_before.print_linkedList()
res = swap_LinkedList(n1)
L1 = LinkedList()
L1.head.next = res
L1.print_linkedList()
三、反转链表3
给定一个链表,传入一个正整数k,将k个范围内的链表中的节点进行全部反转,数字k要小于等于链表的长度,在k个范围内反转完成之后,剩下的节点保持原样,和反转之后的节点一同返回,如果k的倍数超过了链表的长度,那么超过的部分也按原样返回
def reverseKGroup(head, k):
# 如果头一个节点是空,或者k的值过于小,小于2,就相当于k=1
# 那就直接将节点返回
if head is None or k < 2:
return head
# 创建一个变量用来遍历,指向头结点
next_head = head
for i in range(k - 1): # 向后移动到指定位置
next_head = next_head.next
if next_head is None:
return head
ret = next_head # 将节点更新,重新赋值给新的变量,作为剩下部分的头结点
current = head # 当前节点指向头节点
while next_head:
tail = current # 尾部给到current
prev = None
for i in range(k):
if next_head:
next_head = next_head.next
nxt = current.next
current.next = prev
prev = current
current = nxt
tail.next = next_head or current
return ret
lst = LinkedList()
lst.insert_last(1)
lst.insert_last(3)
lst.insert_last(5)
lst.insert_last(7)
lst.insert_last(9)
lst.print_linkedList()
lst.head.next = reverseKGroup(lst.head.next, 2)
lst.print_linkedList()
lst.head.next = reverseKGroup(lst.head.next, 3)
lst.print_linkedList()
lst.head.next = reverseKGroup(lst.head.next, 4)
lst.print_linkedList()
lst.head.next = reverseKGroup(lst.head.next, 5)
lst.print_linkedList()
lst.head.next = reverseKGroup(lst.head.next, 7)
lst.print_linkedList()
四、删除排好序的链表当中重复的元素
给一个current_pointer,再给一个next_pointer,用current_pointer指向第一个节点元素,next_pointer是current_pointer.next,如果这两个节点的值相等,那么就向后移动next_pointer,直到current_pointer.value != next_pointer.value,那么此时将current_pointer移动到next_pointer的位置,next_pointer继续向后
def deleteDuplicates(head):
if head == None:
return head
node = head
while node.next:
if node.value == node.next.value:
node.next = node.next.next
else:
node = node.next
return head
l = LinkedList()
l.insert_last(1)
l.insert_last(1)
l.insert_last(3)
l.insert_last(3)
l.insert_last(3)
l.insert_last(5)
l.insert_last(9)
l.insert_last(9)
l.head.next = deleteDuplicates(l.head.next)
l.print_linkedList()
五、在排好序的链表当中删除所有重复过的元素节点
准备两个pointer,一个是current一个是next,如果current.value == next.value,则next向后移动,当current.value != next.value的时候,current 移动到next的位置,next向后移动,最终返回整个链表
def deleteDuplicates(head):
dummy = current = Node(0)
dummy.next = head
while head and head.next:
if head.value == head.next.value:
while head and head.next and head.value == head.next.value:
head = head.next
head = head.next
current.next = head
else:
current = current.next
head = head.next
return dummy.next
l = LinkedList()
l.insert_last(1)
l.insert_last(1)
l.insert_last(3)
l.insert_last(3)
l.insert_last(3)
l.insert_last(5)
l.insert_last(9)
l.insert_last(9)
l.head.next = deleteDuplicates(l.head.next)
l.print_linkedList()