题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
思路:双指针迭代,递归法
注意双指针迭代除了cur和pre两个指针之外,还需要一个辅助的指针temp用来保存cur.next节点的值
解决方法:
1. 递归解法
递归的两个条件:
(1)终止条件:当前节点或下一个节点等于null
(2)在函数内部,改变节点的指向:head.next.next=head
找到当前链表的尾结点,就是反转链表的头结点
分两种情况:当链表只有空节点、到达链表的尾节点
head.next.next=head;这样理解:
如果链表是 1 -> 2 -> 3 -> 4 -> 5,那么此时的cur就是5
而head是4,head的下一个是5,下下一个是空
所以head.next.next 就是4 -> 5
cur是不变的,始终都指向尾节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode cur = reverseList(head.next); //递归
head.next.next = head; //完成节点的反转
head.next = null; //防止链表成环
return cur;
}
}
双指针迭代更好理解
2. 双指针迭代
先申请两个指针:cur pre;
还需要一个辅助的指针temp用来保存cur.next节点的值
pre最初指向null;
cur指向头节点head,然后不断遍历cur,每次遍历到cur时,都将cur的next指向pre;
然后pre和cur都前进一位;
都迭代完时(cur变成null),pre就是最后一个节点了
(temp节点相当于中间变量)
/**
* 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;
ListNode temp = null;
while(cur != null){
temp = cur.next; //保存当前节点的下一个节点
cur.next = pre; //当前节点cur的next指向pre
//cur pre节点同时向前移动一个节点
pre = cur;
cur = temp;
}
return pre;
}
}
如果不用辅助指针temp,代码会这样写这样是错的
while(cur != null){
cur.next = pre;
pre = cur;
cur = cur.next;
}
//代码只会跑一次,之后cur=null ,pre=1
完整代码这样写:不知道为啥运行不出来?
package cn.sxt.arrays;
/**
* 反转链表
* @author Star Ma
*
*/
public class ListNodeTest {
public static class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
public String show() {
return this.val + "->" + (this.next==null ? "null" : this.next.show());
}
}
//递归
public ListNode reverseList(ListNode head){
if(head == null || head.next == null) {
return head;
}
ListNode cur = reverseList(head.next);
head.next.next = head;
head.next = null;
return cur;
}
public void testReverse(){
ListNode a = new ListNode(1);
ListNode b = new ListNode(2);
ListNode c = new ListNode(3);
a.next = b;
b.next = c;
System.out.println(a.show());
}
}