反转链表

1.常见的链表反转有两种方案来解决,一种是经过迭代来修改指针,另外一种方案就是经过递归来实现,两种算法的时间复杂度一致可是递归的空间复杂度更高
迭代
须要注意的是因为是迭代,中间必然会有引用指向的修改,因此咱们就须要一个新的存储变量来方便咱们后面进行指向修改node

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指针

相关文章
相关标签/搜索