题目:反转链表从m-n位置的结点
For example:
Given1->2->3->4->5->NULL, m = 2 and n = 4,
return1->4->3->2->5->NULL.
从第二到第四的结点被反转了。
其中m和n满足条件:
1 ≤ m ≤ n ≤ length of list.
原地交换结点
public 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 prefirst=null;//first的前一个结点
ListNode aftersecond=null;//second的后一个结点
ListNode first=head;//first引用第m个节点
ListNode second=null;//secone引用第n个节点
ListNode p=head;
for(int i=1;i<=n;i++)
{
if(i == m-1)//注意m为1的情况
{
prefirst=p;
first=p.next;
}
if(i == n)
{
second=p;
aftersecond=p.next;
}
p=p.next;
}
Pair pair=reverse(first,second);
if(prefirst == null)
head=pair.head;
else
prefirst.next=pair.head;
pair.rear.next=aftersecond;
return head;
}
//
public Pair reverse(ListNode head,ListNode rear)
{
ListNode pre=head;
ListNode cur=head.next;
while(cur!=rear)
{
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
cur.next=pre;
pre=cur;
rear=head;
head=pre;
Pair pair=new Pair(head,rear);
return pair;
}
//定义内部类Pair存储reverse后的head和rear;
class Pair
{
ListNode head;
ListNode rear;
public Pair(ListNode head,ListNode rear)
{
this.head=head;
this.rear=rear;
}
}
}
仍是逆序,仍考虑到用辅助空间stack.
将m-n的结点依次入栈,并标记与入栈结点相邻的前后两个结点pfirst和psecond
(若m==1,pfirst=null,不管n是否为length of list,对psecond的情况无影响。)
代码如下:
import java.util.*;
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head==null)
return null;
if(m==n)
return head;
Stack<ListNode> stack=new Stack();
//将m-n的结点入栈,将前后相邻的两个结点标记;
int num=1;
ListNode pfirst=null;
ListNode psecond=null;
ListNode p=head;
//特殊情况,m==1时,头结点变更;
if(m==1)
pfirst=null;
for(;num<=n;num++)
{
//记录pfirst;
if(num<m)
{
if(num==m-1)
{
pfirst=p;
}
p=p.next;
}
else if(num>=m&&num<=n)
{
stack.push(p);
p=p.next;
}
}
//记录psecond,psecond的一般情况仍适用于n=length of list的特殊情况;
psecond=p;
//开始操作链表;
if(pfirst==null)
{
head=stack.pop();
pfirst=head;
}
while(!stack.empty())
{
pfirst.next=stack.pop();
pfirst=pfirst.next;
}
pfirst.next=psecond;
return head;
}
}