题目描述:
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明: 1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
思路:
可以根据反转的起始点将链表分为三个部分,反转中间部分,结束后将三个链表连接到一起即可。
这里需要注意的是,中间链表反转后尾节点不是指向空节点而是指向第三段链表的头结点,所以初始节点设为n3。
代码实现如下:
/**
* 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) {
int count = 0 ;
ListNode pre = null;
ListNode next = null;
ListNode n1 = null;//记录第一段链表的末尾节点
ListNode n2 = null;//记录第二段链表的起始节点
ListNode n3 = null;//记录第三段链表的起始节点
ListNode n4 = null;//记录第二段链表的末尾节点
ListNode cur = head;
while(cur != null){
count++;
if(count == m){//第一个断点的位置。
n1 = pre;//找到第一个链表的末尾
n2 = cur;//找到第二个链表的起始点
}
if(count == n){
n4 = cur;//找到第二个链表的末尾
n3 = cur.next;//找到第三个链表的起始点。
cur.next = null;
break;
}
pre = cur;
cur = cur.next;
}
//将中间链表进行反转并和第三个链表连接起来
pre = n3;
while(n2 != null){
next = n2.next;
n2.next = pre;
pre = n2;
n2 = next;
}
//将第一段和后面的链表连接起来
if(n1 != null){
n1.next = n4;
}
if(n1 != null){//如果第一段为非空链表,则应该返回其实输入头结点。
return head;
}else{//如果第一段为空链表,则应该返回第二段的末尾节点。
return n4;
}
}
}