题目
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
双指针法
首先可以想到的是重新定义一个数组,实现对链表的反转,但是这样做实际上是对内存空间的浪费。
只需要改变链表的next指针的指向,就可以直接反转链表。
- 双指针法
首先定义一个cur指针,指向头节点,再定义一个pre指针,初始化为null; 然后开始反转,如果直接反转,那么cur->next在更新之后会指向pre,之前的cur->next就找不到了,因此应该定义一个节点tmp,保存cur->next。
之后移动pre和cur指针即可,最后cur指针指向null,循环结束,反转完毕,这是要return pre,因此cur为空,而pre指针指向反转后的链表。 - 代码
class Solution{
// 链表节点定义
public class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
public ListNode reverseList(ListNode head) {
ListNode pre = null; // 定义一个pre节点,指向null
ListNode cur = head; // 定义一个cur节点,指向head
ListNode tmp = new ListNode(); // 定义一个tmp节点,保存cur.next
while (cur != null){
tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
递归法
将指针移动的操作使用递归进行。
- 代码
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
public ListNode reverse(ListNode prev,ListNode cur){
if (cur == null){
return prev;
}
ListNode temp = null;
temp = cur.next; // 保存下一个节点
cur.next = prev; // 反转
return reverse(cur,temp);
}
}