【问题标题】:Reverse alternate elements and append to end of the list反转备用元素并附加到列表末尾
【发布时间】:2014-02-07 08:11:19
【问题描述】:
给定一个链表 a->x->b->y->c->z ,我们需要反转备用元素并附加到链表的末尾。即输出为a->b->c->z->y->x。
我有一个 O(n) 解决方案,但它需要额外的内存,我们取 2 个列表并分别用备用元素填充它,所以这两个列表是 a b c 和 x y z 然后我们将反转第二个列表并将其附加到第一个的尾巴,这样它就变成了 b c z y x 。
我的问题是我们能做到吗?或者还有其他相同的算法吗?
【问题讨论】:
标签:
algorithm
pointers
language-agnostic
linked-list
【解决方案1】:
基本思路:
存储x。
使a 指向b。
使 y 指向存储的元素 (x)。
使b 指向c。
等等
最后,使奇数位置的最后一个元素指向存储的元素。
伪代码:(简化的列表末尾检查可读性)
current = startOfList
stored = NULL
while !endOfList
temp = current.next
current.next = current.next.next
temp.next = stored
stored = temp
current = current.next
current.next = stored
复杂性:
O(n) 时间,O(1) 空间。
【解决方案2】:
这是递归模式下的逻辑
public static Node alRev(Node head)
{
if (head == null) return head;
if (head.next != null)
{
if (head.next.next != null)
{
Node n = head.next;
head.next = head.next.next;
n.next = null;
Node temp = alRev(head.next);
if (temp != null){
temp.next = n;
return n;
}
}
else
return head.next;
}
else
return head;
return null;
}
【解决方案3】:
这是最近亚马逊采访的一个问题,idea看起来不错,好像没有什么花招。
【解决方案4】:
带有 cmets 的 Java 代码:
static void change(Node n)
{
if(n == null)
return;
Node current = n;
Node next = null, prev = null;
while(current != null && current.next != null)
{
// One of the alternate node which is to be reversed.
Node temp = current.next;
current.next = temp.next;
// Reverse the alternate node by changing its next pointer.
temp.next = next;
next = temp;
// This node will be used in the final step
// outside the loop to attach reversed nodes.
prev = current;
current = current.next;
}
// If there are odd number of nodes in the linked list.
if(current != null)
prev = current;
// Attach the reversed list to the unreversed list.
prev.next = next;
}
【解决方案5】:
这里的 c 代码不使用任何额外空间来执行此操作..享受并玩得开心
如有任何疑问,请随时询问
#include<stdio.h>
#include<stdlib.h>
int n;
struct link
{
int val;
struct link *next;
};
void show(struct link *);
void addatbeg(struct link **p,int num)
{
struct link *temp,*help;
help=*p;
temp=(struct link *)malloc(sizeof(struct link));
temp->val=num;
temp->next=NULL;
if(help==NULL)
{
*p=temp;
}
else
{
temp->next=help;
*p=temp;
}
n++;
show(*p);
}
void revapp(struct link **p)
{
struct link *temp,*help,*q,*r;
r=NULL;
temp=*p;
help=*p;
while(temp->next!=NULL)
{
temp=temp->next;
q=r; //this portion will revrse the even position numbers
r=temp;
temp=temp->next;
//for making a connection between odd place numbers
if(help->next->next!=NULL)
{
help->next=temp;
help=help->next;
r->next=q;
}
else
{
r->next=q;
help->next=r;
show(*p);
return;
}
}
}
void show(struct link *q)
{
struct link *temp=q;
printf("\t");
while(q!=NULL )
{
printf("%d ->",q->val);
q=q->next;
if(q==temp)
{
printf("NULL\n");
return;
}
}
printf("NULL\n");
}
int main()
{
n=0;
struct link *p;
p=NULL;
// you can take user defined input but here i am solving it on predefined list
addatbeg(&p,8);
addatbeg(&p,7);
addatbeg(&p,6);
addatbeg(&p,5);
addatbeg(&p,4);
addatbeg(&p,3);
addatbeg(&p,2);
addatbeg(&p,1);
revapp(&p);
return 0;
}`