1. 常见的链表反转有两种计划来解决,一种是通过迭代来批改指针,另一种计划就是通过递归来实现,两种算法的工夫复杂度统一然而递归的空间复杂度更高
迭代
须要留神的是因为是迭代,两头必然会有援用指向的批改,所以咱们就须要一个新的存储变量来不便咱们前面进行指向批改
ListNode prev=null;
while(head!=null){
ListNode node =head.next;
head.next=prev;
prev=head;
head=node;
}
递归
咱们须要思考的是下层和上层的关系,而不是去思考具体递归的值,同时由教训可知,肯定要思考的两个点就是临界值的确定和函数定义
之前 k 神的解法就十分好
函数定义中须要思考的点:
入参、须要实现什么、返回值
if(head.next==null){return head;}
ListNode last=reverse(head.next);
head.next.next=head;
head.next=null;
return last;
2. 局部反转
局部反转的话须要思考的问题:
1. 须要一个虚构头节点 dummyNode
2. 须要一个节点 pre,代表 left 之前的一个节点
3. 先找到指标链表的头节点 left,而后通过 right-left+1, 找到指标链表的尾节点 right
4.pre.next=null;right.next=null;
5.pre.next=right; left.next=curr;
3. 究极体 k 个一组来进行反转
这个也有说法,以 k 个为一组的时候,咱们能够了解为几个区间,第一个就是已反转区间,第二个就是待反转区间,第三个就是未反转区间,而且为了不便咱们退出了虚构头节点(这是一个小细节,根本链表反转都须要加这个)
1. 首先明确咱们须要自定义四个变量,pre,next,start,end 是两两对应的
2. 如果最初的几个不够 k 个的话,那么咱们就须要将最初一个区间拼接到之前的区间上
3.
ListNode start=pre;
ListNode next=end.next;
end.next=null;
pre.next=revese(start);
start.next=next;
pre=start;
end=prev;
下面这里就是最外围的逻辑代码
4.reverse(ListNode head)
这里进行迭代的时候判断条件应该是 curr!=null