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;
}
posted @ 2022-05-28 18:43  wesson2019  阅读(19)  评论(0编辑  收藏  举报