Leetcode 92-Reverse Linked List II

题目:

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

说明:
1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

  这题利用了翻转链表的1的知识,只不过需要实现头拼接和尾拼接。为了实现头拼接和尾拼接,需要找四个关键的节点,反转点m和m前一个点,反转点n和n后的第一个点,将m连至n+1,n连到m-1。另外还需要注意头节点,写起来感觉很麻烦,算是刷链表题碰到最麻烦的一题了。

  先贴上代码。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        
        if(head==null||head.next==null)
        {
            return head;
        }
        
        if(m==n)
        {
            return head;
        }
     
        ListNode pre=new ListNode(0);//现在前一位
        ListNode cur=head;//现在一位
        ListNode gra=new ListNode(0);//头节点
        ListNode last=null;//n后一位
        gra.next=head;        
        pre=gra;
        while(cur!=null)
        {
            if(m==1)
            {
              ListNode normal=cur;   
              last=reverse(cur,pre,n);
              normal.next=last;
              break;
            }
            pre=pre.next;
            cur=cur.next;
            m--;
            n--;
            
        }
        
        return gra.next;
        
        
    }
    
    public ListNode reverse(ListNode mhead,ListNode phead,int n)
    {
        ListNode p=null;
        ListNode q=mhead;
        while(n>0)
        {
            ListNode temp=q.next;
            q.next=p;
            p=q;
            q=temp;
            n--;
        
        }
        phead.next=p;
    return q;     
    }    
   
    
}

 注意点有很多:

1.pre是m-1,cur是m,q是n+1,p是n;

2.在反转时,由于是m=1进入的,而n肯定比m大,所以n起码为2,(一开始没想明白);第一次反转是以null开始的,所有n=2,实际上只反转了当前节点的后一个节点(也可以理解成把当前节点和后面的节点反转了)。

3.当m=1时,gra顺着pre指向p,也就是n点为头节点。m!=1时,gra和pre分离,gra依然指向头结点。(这里想了半天怎么找头结点)。

 

上结论图:

Leetcode 92-Reverse Linked List II