1. 题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例1:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
示例2:
输入: head = [1,2]
输出: [2,1]
示例3:
输入: head = []
输出: []
2. 解法
2.1 递归
今天的递归也是一看就会,一写就废呢。
递归都是和动态规划中的状态转移方程一样,就是先处理头节点,剩下的一部分放进函数递归。
所以我这里只讲三个点,比较容易理解一点。
换位置需要起码两个点,所以递归到倒数最后一个点就可以直接返回。
先5和4换位置(暂定1->2->3->4->5这样的链表)
return 之后3还是指向4,需要先将4指向3(其实到这一步已经完成了转向)
但是要把3->null,不然会形成环,链表形成环就容易死循环。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
2.2 迭代
我的思路是这样的,首先要有一个新的头节点,然后进入循环,用temp节点储存第二节点。然后将head->next接在prev->next,再将prev->next指向head。最后有一个新的head进入循环。可以看下图(本来应该是动图,但是我不太会画,就凑活看,还是很清楚的,temp应该只是一个指针,没有框,画的时候忘了)
Java代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode preserve = new ListNode(-1);
ListNode prev = preserve;
while(head != null){
ListNode temp = head.next;
head.next = prev.next;
prev.next = head;
head = temp;
}
return prev.next;
}
}
2.3 双指针
双指针我懒得画图了,可以试试自己画,链表画图会直观很多。
比如1->2->3->4->5这样的链表,假设cur指向1前面的null,pre指向1.
此时只需要将1->cur,pre->2,cur->1就行。
其中因为2会没有指针,会找不到,所以用一个temp指针存住。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = null,pre = head;
while(pre!=null){
ListNode temp = pre.next;
pre.next = cur;
cur = pre;
pre = temp;
}
return cur;
}
}