定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
题目分析:
反转链表是一种十分常见的需求,其中最常见的解法是递归,还有一种解法是双指针,除此之外还有一种利用栈的先进后出特性的解法。
话不多说,上代码。
递归法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
return invert(head,null);
}
private ListNode invert(ListNode cur,ListNode pre){
if(cur == null){ //递归终止条件
return pre;
}
ListNode res = invert(cur.next,cur);//继续递归后续节点
cur.next = pre;//修改节点引用指向
return res;//返回反转链表的头节点
}
}
双指针法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
while(cur != null){
ListNode t = cur.next; //将当前节点的后继节点暂存
cur.next = pre; //修改pre.next的引用指向前一个节点
pre = cur;//pre节点继续向后
cur = t;//cur节点向后遍历
}
return pre;
}
}
栈法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
LinkedList<ListNode> stack = new LinkedList<>();
if(head == null){
return null;
}
/*
循环遍历每个节点,将每个节点依次放入栈中
*/
while(head != null){
stack.push(head);
head = head.next;
}
ListNode res = stack.pop();//拿出栈中的最后一个节点,即为反转后的头节点
ListNode t = res;
while(!stack.isEmpty()){//依次取出栈中的节点
ListNode node = stack.pop();
t.next = node;//修改反转后节点的下一节点
t = node;
}
t.next = null; //将最后一个节点的next改为null。
return res;
}
}