92. Reverse Linked List II
给定链表的区间起始位置 start(从0开始), end,反转这个两个位置区间内的所有结点。
int[] arr = new[] { 1, 4, 2, 3, 6, 5, 2 };
SLinkedList<int> slist = new SLinkedList<int>();
slist.AppendRange(arr);
Console.WriteLine("Before: " + slist.Print());
var rslt = slist.ReverseBetween(2, 4);
Console.WriteLine(" After: " + rslt.Print());
/// <summary>
/// 链表区间反转
/// </summary>
/// <typeparam name="T">结点类型</typeparam>
/// <param name="source">源链表</param>
/// <param name="start">区间开始位置(0起始)</param>
/// <param name="end">区间结束位置</param>
/// <returns></returns>
public static SLinkedList<T> ReverseBetween<T>(this SLinkedList<T> source, int start, int end) where T : IComparable<T>
{
if (source.IsEmpty())
{
return new SLinkedList<T>();
}
if (source.Head == null || source.Head.Next == null)
{
return source;
}
if (start < 0)
{
start = 0;
}
if (end >= source.Count)
{
end = source.Count - 1;
}
var tmp = new SLinkedList<T>(source);
// 找到start结点的前继,采用头插法
var head = ReverseBetweenImp(tmp.Head, start, end);
tmp.Clear();
return new SLinkedList<T>(head);
}
private static SLinkedListNode<T> ReverseBetweenImp<T>(SLinkedListNode<T> head, int start, int end) where T : IComparable<T>
{
if (head == null || start >= end)
{
return head;
}
var newHead = new SLinkedListNode<T>();
newHead.Next = head;
var pre = newHead;
for (int i = 0; pre.Next != null && i < start; i++)
{
pre = pre.Next;
}
if (pre.Next == null)
{
return head;
}
var cur = pre.Next;
for (int i = 0; i < end - start; i++)
{
var tmp = pre.Next;
pre.Next = cur.Next;
cur.Next = cur.Next.Next;
pre.Next.Next = tmp;
}
return newHead.Next;
}