力扣 92. 反转链表 II

50 阅读1分钟

image.png

image.png

我想到用一次遍历的方法去找到要反转的位置,然后把left到right区间内的结点反转,步骤和力扣上206反转链表方法一样。在遍历到left位置之前要保存left的前一个位置tail1,注意还要保存left位置的结点为tail2,tail2是反转后的[left, right]范围链表的最后一个元素,在遍历到right位置时,用来遍历的结点tmphead刚好指向right的下一个元素。做完反转,让tail1.next指向pre,pre是反转过程中的right位置的节点,tail2.next指向tmphead。 有个细节需要注意,以下代码的pre置为null是防止形成环。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode pre=null, tmp=null;
        ListNode tmphead=new ListNode();
        tmphead.next=head;
        ListNode dummyhead=tmphead;
        int i=0;
        //保存第一段的尾巴tail1
        for(i=0; i<left; i++){
            pre=tmphead;
            tmphead=tmphead.next;
        }
        ListNode tail1=pre;
        pre=null;
        //第二段反转后的尾巴tail2
        ListNode tail2=tmphead;

        //逆序
        while(i<=right){
            tmp=tmphead.next;
            tmphead.next=pre;
            pre=tmphead;
            tmphead=tmp;
            i++;
        }
        tail1.next=pre;
        tail2.next=tmphead;
        return dummyhead.next;
    }
}