问题
LettCode206:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
链接: 题目
例如: 输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
解题思路:
如何使用指针,记录每个节点与下一个结点的关系。
1.虚拟头结点辅助反转
链表插入元素的时候,如何处理头结点是一个比较麻烦的问题。因此可以先建立一个虚拟结点dumy,并且另dumy.next = head,这样可以简化操作。
如下图,将对链表{1-> 2-> 3-> 4-> 5} 进行反转,先建立结点dumy,并且令dumy.next = node(1),接下来每次从旧的链表拆下来一个结点到dumy后,在调整其他结点。
这个过程就是前面的带虚拟结点的插入操作,每走一步都要考虑各种指针怎么指,既要将结点摘下来接到对应的位置上,还要保证后续结点能够找到。
public static ListNode reverseList(ListNode head){
//虚拟头结点
ListNode dumy = new ListNode(-1);
dumy.next = head;
while(cur != null){
ListNode nex = cur.next;
cur.next = dumy.next;
dumy.next = cur;
cur = next;
}
return dumy.next;
}
也可以如下:
public static ListNode reverseList(ListNode head) {
/*
需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,
*/
ListNode cur = head;
ListNode prev = null;
ListNode temp = null;
while (cur != null){
temp = cur.next;
cur.next = prev;
prev = cur;
cur = temp;
}
return prev;
}
2.直接操作链表实现反转
如何不借助虚拟结点,实现链表反转呢?
先观察反转前后的结构和指针位置:
如下图,是在调整4结点的时候,链表及链表指针发生的变化。
cur.next 指向 prev
随后两个指针再向下移动一位。
public static ListNode reverseList(ListNode head){
ListNode prev = null;
ListNode cur = head;
while (cur != null){
ListNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}