题目:
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2] 输出:[2,1]
示例 3:
输入:head = [] 输出:[]
思路:
本题可以采用两个方法,分别是双指针法和递归法,内部逻辑相同,但是递归代码更简短。如果不了解双指针法,乍一看递归法,会觉得很难理解。
其实双指针法的逻辑是,定义两个指针,一个为pre一个为cur,分别表示当前要操作的链表节点以及在其前面的节点,在cur不为null的循环中,一直遍历,每一次遍历用temp临时指针记录cur的next,再使cur指向pre,之后整体使cur和pre向后移动(pre指向cur,cur指向temp),直到cur指向null。
递归法与之逻辑相同,创建一个方法名为reverseNode,给两个形参分为cur和pre。递归首先要卡找出口,出口就是cur等于null的时候,递归就结束了,因此一开始给一个if判断。之后在其中完成链表倒置的操作,即使得cur指向pre,并记录cur的next位置给temp,之后继续递归直到cur到null再逐层返回。主函数中调用reverseNode方法,给形参为(head,null)因为pre是指向null,head为头节点。
代码:
1、双指针法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
// 双指针法
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
while(cur != null){
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
2、递归法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
// 递归遍历法
class Solution {
public ListNode reverseList(ListNode head) {
return reverseNode(head,null);
}
public ListNode reverseNode(ListNode cur,ListNode pre){
if(cur == null){
return pre;
}
ListNode temp = cur.next;
cur.next = pre;
return reverseNode(temp,cur);
}
}