这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
今天的这道题,他看起来好麻烦的样子,但其实,我们不要被他的等级吓到了,做起来还是很好去实现的,我们只要理顺了,我们链表重新排列之后的顺序是什么样子的就十分好做了。
我们把这个过程分为三部分
1.把链表从中间分割成两部分,返回中间节点
//我们使用快慢指针,慢指针走一步,快指针走两步,当快指针走到终点时,慢指针处于中间位置
public ListNode mid(ListNode head){
ListNode slow = head;
ListNode fast = head;
while(fast.next!=null && fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
return slow;
}
2.反转后半部分链表
//这个就是我们正常反转链表的操作
public ListNode reverseList(ListNode head){
ListNode p = null;
ListNode n = head;
while(n!=null){
ListNode temp = n.next;
n.next = p;
p=n;
n=temp;
}
return p;
}
3.一次合并两部分链表
public void mergeList(ListNode l1,ListNode l2){
ListNode a=l1;
ListNode b=l2;
while(a!=null && b!=null){
ListNode atemp = a.next;
ListNode btemp = b.next;
a.next=b;
a=atemp;
b.next=a;
b=btemp;
}
}
当我们有这些方法之后,我们简单的操作一下
public void reorderList(ListNode head) {
if(head==null){
return;
}
//获取我们的中间节点
ListNode mid = mid(head);
ListNode a=head;
ListNode b=mid.next;
//我们的a链表现在表示的是全部的链表,我们要从中间,将链表截断,就需要让它中间的指针指向null就可以了
mid.next=null;
b=reverseList(b);
mergeList(a,b);
}
之前就做了很多的链表的题,有过反转链表,有过合并链表,这一道题像把链表很多的知识点都集中起来,一起去运用,如果直接没有看过其他的题有这种办法去解题还是很难的,但是其它类型的题我刚刚做完,就遇上了。