143. 重排链表
给定一个单链表?L ?的头节点?head ?,单链表?L ?表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]输出:[1,4,2,3]
示例 2:
输入:head = [1,2,3,4,5]输出:[1,5,2,4,3]
思路:
? 这道题的要求看起来比较复杂,尤其是在操作链表的情况下实现这种要求。其实这道题的意思就等同于:取倒数第一个节点插入第一个节点后面,取倒数第二个节点插入第二个节点后面……直到取到中间节点为止。
? 但是怎么倒着取出链表当中的节点呢,在链表中几乎是不可能实现的,所以我们需要利用数组,先将链表逐一放入数组中,然后就可以倒着从数组中取出节点了,取出后就按照我们的思路进行最基础的链表插入操作。
? 重复一下总体思路:当把链表存入数组后,从后向前遍历数组至中间位置,将每次遍历拿到的值插入到前半部分链表中。(在a节点和b节点之间插入节点的基本方式是先暂存b节点,使a.next等于插入节点,再使插入节点.next等于b节点,不再多说。)
代码:
class?Solution(object):
????def?reorderList(self,?head):
????????lis?=?[]#定义存放链表的数组lis
????????h=head
????????while(h):#先把节点都存进去
????????????lis.append(h)
????????????h=h.next
????????lenth?=?len(lis)
????????if?lenth<=1:#处理特殊情况
????????????return?
????????m?=?-1#m为-1,从后往前开始
????????for?i?in?range(lenth//2):#操作前一半即可
????????????nex?=?lis[i].next #暂存这个点的next
????????????lis[i].next=lis[m]#把这个点指向lis[m],lis[m]从最后开始往前走
????????????lis[m].next=nex #lis[m]再连上暂存的点
#上面这三部就是经典的插入节点而已
????????????m-=1 #m逐步往前
????????lis[i+1].next?=?None?#最后这句话得有?遍历到最后的下一个节点指向None
#否则链表还是个环,系统判断一直循环?就超时报错
? 最后要注意,需要将新的末尾节点指向None,否则链表变成了环形链表,不符合题意,提交后也无法让系统正常验证。
|