这是一个问题。
给出链接列表,如a1-a2-a3-a4-b1-b2-b3-b4。将其转换为a1-b1-a2-b2-a3-b3-a4-b4。
我的算法效率低下。
需要你的想法。
答案 0 :(得分:2)
您可以使用C#LinkedList
类轻松完成此操作。
首先扫描列表以找到b1
节点。您有另一个从list.First
开始的变量。然后将b1
节点移动到第一个节点之后,移动到b2
,将另一个变量移动到a2
,然后重复,直到到达列表末尾。
它看起来像这样:
var aNode = list.First();
var bNode = list.First();
// scan the list looking for the first `b` node.
while (!(bNode.Value[0] == 'b'))
bNode = bNode.Next;
// now interleave the elements
while (bNode != null)
{
var nextB = bNode.Next;
var nextA = aNode.Next;
list.Remove(bNode);
list.AddAfter(aNode, bNode);
aNode = nextA;
bNode = nextB;
}
如果a
个节点至少有b
个节点,则上述操作将起作用。如果'b'节点可能比'a'节点多,那么你必须在每次迭代后检查aNode
值,以确保你没有走得太远。这很容易完成:
while (bNode != null && aNode.Value[0] == 'a')
答案 1 :(得分:1)
或者您可以浏览链表,如果项目以“a”开头,则将它们添加到队列“A”,如果是“b”,则将它们添加到队列“B”,然后将项目A和B出列在循环中。
答案 2 :(得分:1)
详细信息将取决于列表的实现方式,但这里有一个想法:
有一个指针ap,从原始列表的开头开始;得到第二个bp,指向第一个b节点。
现在,反复将bp指向的项目移动到ap之后,并将ap前进到下一个a& bp到下一个b。
由于每个指针最多遍历一次列表,因此整个算法都是线性的。
答案 3 :(得分:1)
有两个指针,首先指向开头,例如a
,第二个指向中间(b序列开始),例如b
,然后,在循环中有一些停止条件:
aNext = a.next
bNext = b.next
a.next = b
b.next = aNext
a = aNext
b = bNext
答案 4 :(得分:1)
测试了以下代码,它运行正常 -
public void arrangeInPairs()
{
if(head == null)
return;
Node slow = head;
Node fast = head;
while(fast != null)
{
slow = slow.next;
fast = fast.next.next;
}//now slow is at the start of 2nd sequence (b1) and fast is null
//move back fast to the beginning
fast = head;
while(slow.next != null)
{
Node sTemp = slow.next;
Node fTemp = fast.next;
fast.next = slow;
slow.next = fTemp;
fast = fTemp;
slow = sTemp;
}
fast.next = slow; //if you skip this then a4 will be still pointing to b1 causing a cyclic loop
slow.next = null;// last element would be slow (b4) so assign its next to null
printList(); //a1 b1 a2 b2 a3 b3 a4 b4
}
答案 5 :(得分:0)
迭代n-1步。
例如:n = 4
a1 a2 a3 a4 b1 b2 b3 b4
a1 a2 a3 b1 a4 b2 b3 b4
a1 a2 b1 a3 b2 a4 b3 b4
a1 b1 a2 b2 a3 b3 a4 b4
时间复杂度:O(n)
空间复杂度:O(1)