反转链表(206)
大家好,我是小笙,是一名热爱算法的程序员,我觉得如果把算法当成一种面试必备的任务,是一种压抑而又枯燥的!我想重新定义一下练习算法的目的 – 益脑,你要真正投入到对算法的喜欢,不要仅局限于提交成功,而应该更关注算法的延展性和互通性!
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:输入:head = [1,2]
输出:[2,1]
示例 3:输入:head = []
输出:[]提示:链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
插入节点
假设输入:head = [1,2,3,4,5] ; 输出:[5,4,3,2,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) {
if(head == null) return null;
ListNode list = new ListNode(0);
while(head != null){
ListNode Node = head;
head = head.next;
Node.next = list.next;
list.next = Node;
}
return list.next;
}
}
递归算法
我们很多时候对于递归算法都有种排斥,那就是无从入手,原本正向推导就是件不容易的事,现在还要先反向构思,这难度可想而知,对初学者特别不友好。
不妨听我说说递归算法解决思路:
我觉得在使用递归算法之前,你先问问自己三个问题
- 判断递归结束的条件是什么?(并且该结束条件最终是一定会执行到的,不然就会造成死循环)
- 该递归方法的作用是什么? 换句话来说你想通过这个递归方法得到什么?
- 得到该递归方法之后,我们还需要什么才可以达到题目的要求?
先献上我的完整代码
/**
* 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) {
if(head == null) return null;
else if(head.next == null){
return head;
}else{
ListNode list = reverseList(head.next);
ListNode Node = list;
while(Node.next != null){
Node = Node.next;
}
Node.next = head;
Node.next.next = null;
return list;
}
}
}
接下来且听我慢慢分析
判断递归结束的条件:
// 这个条件也是一定会执行到的
else if(head.next == null){
return head;
}
该递归方法的作用:
本题的作用就是获得head反转链表(就是题目要求的实现)
// reverseList(head.next)这个作用就是获得head.next的反转链表,但是不要问为什么,因为你在这一步得不到答案,你只要假定这个方法就是这个作用就可以了
ListNode list = reverseList(head.next);
得到该递归方法之后,我们还需要什么才可以达到题目的要求:
head.next 以后的链表是反转的,那我们只要在该节点的最后添加上head的节点是不是整体就实现了反转
然后我们反思一下是不是每次调用递归方法后我们都是干同一件事,那就是把第一节点移动到最后,这不就实现了链表最后的反转嘛(寻找到这个共同特征,那么递归方法就迎刃而解了)
// 遍历 head.next反转后的链表,并在最后接上当前的head的节点
ListNode Node = list;
while(Node.next != null){
Node = Node.next;
}
Node.next = head;
Node.next.next = null;
return list;