题目:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例1:
输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5]
输入:head = [5], left = 1, right = 1 输出:[5]
解法一:(穿针引线)
解题思路:
在头结点前设置一个哑结点dummy,并指向head头结点。
首先将pre移动到left前一个元素位置,并记录下cur=pre.next
之后就是进行两两交换元素位置。
移动的思想就是两两移动,最关键的是整个过程pre是不移动的,通过next.next=pre.next仅仅反复改变指针方向,一直是cur随着元素位置在变化。每次改变的是pre指向的下一个元素和next元素。
#穿针引线
dummy=ListNode(0,head)
pre=dummy
for i in range(left-1):
pre=pre.next #将pre移动到left位置的前一个元素
cur=pre.next #设置第一个需要移动的元素(也就是left位置的元素)
#移动的思想就是两两移动,整个过程pre是不移动的,仅仅反复改变指针方向,一直是cur随着元素位置在变化
for i in range(right-left):
next=cur.next
cur.next=next.next #用cur.next指针指向记录下一个需要交换的位置
next.next=pre.next #后面这两个指针指向是为了交换当前需要换位置的两个元素
pre.next=next
return dummy.next
解法二:(栈)
解题思路:
在头结点前设置一个哑结点dummy,并指向head头结点。设置空列表stack。
left_用来遍历链表。
第一步,首先将pre移动到left前一个元素位置,并用head记录下这个位置。
第二步,将left_从left位置遍历到right位置,同时加每个元素添加到stack中。遍历完成后left_停在right位置,此时就需要记录right位置后面那个元素的地址 k 。
现在就可以将left前一个位置元素指向right位置的元素,也就是head.next=left_.
第三步:由于left_目前就位于right位置,就将stack中最后一个元素删除。然后再将left_.next指向列表最后一个元素并将left_移动到当前元素,直到stack为空。(这个过程就是将left到right位置中的所有元素调换位置)。stack为空,说明left_已位于left位置。
最后将left_指向之前记录下来的 k 位置,最后就可以返回dummy.next链表了。。
#栈
dummy=ListNode(0,head) #增加哑结点,就不用考虑left=1
left_=dummy
stack=list()
for i in range(left-1): #left_移动到left前一个元素
left_=left_.next
head=left_ #head和left_同时先放到left前一个元素位置
for i in range(right-left+1): #left_从left位置一直移动到right位置,并将每个元素记录在stack中
left_=left_.next
stack.append(left_)
k=left_.next #记录right位置后面的那个元素地址
head.next=left_ #可以价格head.next指向right位置了
stack.pop() #left_目前在right位置,stack可以把right位置元素删除
if stack:
#只要stack不空,就将left_.next指向stack中最后一个元素,同时left_移动到这个元素位置,最后left_就在left位置
for i in range(right-left):
left_.next=stack.pop()
left_=left_.next
left_.next=k #最后就将整个调整好指针方向的最后一个元素指向right位置后面的元素
return dummy.next
知识点:
知识1:
今天反复用到的一个用法,将链表指针指向列表中某个元素,由于这个元素与链表中的某个元素值相同,这个元素也等同于在链表中等值元素位置。