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