难度等级:简单
上一篇算法:
力扣此题地址:
1.题目:反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
2.解题思路:
两种方式:1.迭代法实现 2.递归方式实现(比较难懂)
1.迭代法实现:
也就相当于把指针的方向反转,之前是从前往后指,现在从后往前指。
2.递归方式实现(比较难懂)
思路:递归反转就是从原链表的第一个存储节点开始,依次递归调用反转每一个结点, // 直到把最后一个反转完毕,真个链表就反转完毕了。
3.代码实现:
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 pre = null;//定义一个前指针,另后面的结点依次指向当前结点的前一个结点
ListNode cur = head;//定义一个cur指针用于遍历当前链表结点
ListNode next = null;//next指针指向cur的下一个结点
while(cur != null){
next = cur.next;//这里将cur.next赋值给next,方便后面cur的遍历,不然cur.next被赋值pre,值就变了。
cur.next = pre;//将cur的next指针指向pre,如果cur是head话,就指向null。
pre = cur;//令pre指针指向cur结点,这样cur的下一个结点指向pre的时候就相当于指向cur
cur = next;//移动cur到cur的下一个结点
}
return pre;
}
}
2.递归方式:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
// 寻找递归终止条件
// 1、head 指向的结点为 null
// 2、head 指向的结点的下一个结点为 null
// 在这两种情况下,反转之后的结果还是它自己本身
if( head == null || head.next == null) return head;
// 不断的通过递归调用,直到无法递归下去,递归的最小粒度是在最后一个节点
// 因为到最后一个节点的时候,由于当前节点 head 的 next 节点是空,所以会直接返回 head
ListNode cur = reverseList(head.next);
// 比如原链表为 1 --> 2 --> 3 --> 4 --> 5
// 第一次执行下面代码的时候,head 为 4,那么 head.next = 5
// 那么 head.next.next 就是 5.next ,意思就是去设置 5 的下一个节点
// 等号右侧为 head,意思就是设置 5 的下一个节点是 4
// 这里出现了两个 next
// 第一个 next 是「获取」 head 的下一节点
// 第二个 next 是「设置」 当前节点的下一节点为等号右侧的值
head.next.next = head;
// head 原来的下一节点指向自己,所以 head 自己本身就不能再指向原来的下一节点了
// 否则会发生无限循环
head.next = null;
// 我们把每次反转后的结果传递给上一层
return cur;
}
}
参考单链表里的反转链表(1.用反转头实现 2.用递归实现):