题目:
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
.
题意:
给定一个单链表,以及需要反转的开始节点和结束节点,然后对这中间一段进行反转节点操作。
题解:
我采用多设置一个头结点,也就是在已经有的单链表的第一个节点之前再设置一个节点,然后就是一个一个节点遍历下去,直到发现第一个要反转的节点为止,然后我设置了一个count变量,这个变量用来判断是不是从头结点开始反转,因为如果从头结点开始反转,那么之前的head就要变了,要重新将已经反转之后的那个节点赋给这个head。这个pre前置节点因为表示的是当前节点的前一个节点,所以在反转的时候,需要考虑为空和不为空的情况,为空就是反转从头结点开始,否则就表示不是从头结点开始反转。
public ListNode reverseBetween(ListNode head,int m,int n)
{
Stack<ListNode> stack = new Stack<ListNode>();
if(head == null || head.next == null)
return head;
ListNode node = head;
ListNode pre = null;
int count = 1;
while(node != null)
{
if(count != m)
{
pre = node;
node = node.next;
count++;
}
else
{
int num = 1;
while(num <= (n - m + 1))
{
stack.push(node);
node = node.next;
num++;
}
ListNode end = node; //这个表示的是需要反转的最后的那个节点的下一个节点,因为要串起来,所以必须要先保留这个节点
while(!stack.isEmpty())
{
ListNode first = stack.pop();
if(pre == null && count == 1)
{
head = first;
pre = first;
}
else
{
pre.next = first;
pre = pre.next;
}
count++;
}
pre.next = end; //其实在这里,这个pre表示的是当前节点了,因为已经反转过了,这里要特别当心。
}
}
return head;
}