反转链表
Posted ChangZhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反转链表相关的知识,希望对你有一定的参考价值。
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
以上是关于反转链表的主要内容,如果未能解决你的问题,请参考以下文章