我想到用一次遍历的方法去找到要反转的位置,然后把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;
}
}