[Leetcode 92]反转链表II

反转链表II

题目描述

给定单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

测试用例

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

题目链接

思路

  • 1.找到待反转的区间
  • 2.截取该区间进行反转
  • 3.转完再拼接回去(假装无事发生[手动狗头])

区间反转不好处理,那咱至少会链表的整体反转啊,那就把它当作一个链表的整体反转来考虑,怎么考虑把要反转的区间截下,当成一条新链表处理。
如果你对链表的整体反转还不太熟悉,可以先看看这道题[反转链表]。

思路解析

有思路了,代码写起来也就容易些了。

1.定位left、right结点位置,根据给定的left、right确定需要反转的区间,记录下left的前驱结点、和right的后继结点。
[Leetcode 92]反转链表II_第1张图片
记录前驱、后继结点是为了在后期拼接回来时,还能找到原来的“家”。

ListNode pre=dummy;
//找left位置的节点
for(int i=0;i<left-1;i++){
	pre=pre.next;
}
//定位right位置的节点
ListNode post=pre;
for(int j=0;j<right-left+1;j++){
	post=post.next;
}
//记录left、right原连接关系
ListNode leftNode=pre.next;
ListNode curr=post.next;

2.对截取的区间进行反转。
[Leetcode 92]反转链表II_第2张图片

public static ListNode reverse(ListNode head){
      if(head==null){
           return null;
       }
       //因为头节点会发生变化,设置哨兵可以避免复杂情况的讨论
       ListNode dummy=new ListNode(-1);
       dummy.next=head;
       ListNode curr=head;
       ListNode pre=null;

       while(curr!=null){
           ListNode curNext=curr.next;
           //尾节点作为新的头节点
           if(curr.next==null){
               dummy.next=curr;
           }
           //通过改变指针指向,从而实现链表反转
           curr.next=pre;
           pre=curr;
           curr=curNext;
       }
       return dummy.next;
    }

3.反转完成后再重新拼接回来
[Leetcode 92]反转链表II_第3张图片

//将反转后的部分重新拼接回去
pre.next=post;
leftNode.next=curr;
return dummy.next;

整体代码

public class Main {
    public static ListNode reverseBetween(ListNode head, int left, int right) {
        //设置哑结点,避免复杂分类讨论
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode pre=dummy;
        //分别找到left、right指向的位置。
        for(int i=0;i<left-1;i++){
            pre=pre.next;
        }
        ListNode post=pre;
        for(int j=0;j<right-left+1;j++){
            post=post.next;
        }
        //记录left、right原连接关系
        ListNode leftNode=pre.next;
        ListNode curr=post.next;
        //断开原链表连接
        pre.next=null;
        post.next=null;
        //反转
        reverse(leftNode);
        //将反转后的部分重新拼接回去
        pre.next=post;
        leftNode.next=curr;
        return dummy.next;
    }

    public static ListNode reverse(ListNode head){
        if(head==null){
            return null;
        }
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode curr=head;
        ListNode pre=null;

        while(curr!=null){
            ListNode curNext=curr.next;
            if(curr.next==null){
                dummy.next=curr;
            }
            curr.next=pre;
            pre=curr;
            curr=curNext;
        }
        return dummy.next;
    }

总结

链表题一定要画图!!!新手更要画图,不能偷懒!

你可能感兴趣的:(Java习题,链表)