题目原型:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL
, m = 2 and n = 4,
return 1->4->3->2->5->NULL
.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
思路:
我们要找到断开节点位置(m)的前驱preNode和n的后继nextNode,此时只要翻转m到n这段,然后再连上preNode和nextNode即可。
public ListNode reverseBetween(ListNode head, int m, int n)
{
//如果链表为空
if(head==null)
return null;
//如果翻转元素个数为1,也就是不翻转
if(m==n)
return head;
int len = 0;//链表长度
int count = 0;//计数,和m,n进行比较
ListNode p,q = null,r = null,t = null,temp = null;
ListNode preNode = null,nextNode = null;
p = head;
//求链表长度
while(p!=null)
{
len++;
p = p.next;
}
if(m<1||n>len)
return null;
p = head;
while(p!=null)
{
count++;
//如果m==count,此时我们要记录此节点的前驱节点并断开
if(m==count)
{
if(preNode!=null)
preNode.next = null;
t = p;
}
//如果n==count,此时我们要记录此节点的后继,并断开
if(n==count)
{
nextNode = p.next;
p.next = null;
break;
}
//前驱节点只有在count<m的时候才跟踪
if(count<m)
{
preNode = p;
}
p = p.next;
}
//反转中间那段
r = t;//r指向表头,以便最后对接,此时表尾是p
if(t!=null)
q = t.next;
if(t!=null&&t.next!=null)
temp = t.next.next;
while(q!=null)
{
q.next = t;
t = q;
q = temp;
if(temp!=null)
temp = temp.next;
}
//反转后p指向表头,r指向表尾
r.next = nextNode;
//如果preNode为空,说明m==1,此时只要返回翻转后的表头就可以了,如:1->2->3->4,m=1,n=2;此时p是指向2的
if(preNode!=null)
preNode.next = p;
else
return p;
return head;
}