东莞市盛裕绒艺玩具有限公司

东莞市盛裕绒艺玩具有限公司

大班BET最新客服

18513017103
联系方式
全国服务热线: 18513017103

咨询热线:13673261227
联系人:温迪
地址:内蒙古自治省赤峰市 自治区市内蒙克什克腾旗木希嘎乡

单链表-头条面试

来源:大班BET最新客服   发布时间:2019-07-02   点击量:248

大家好,本篇博客将讲述单链表的逆序,希望大家在看这篇博客的时候,手里拿张纸,手写一下过程!!!

 

出现情况:第一轮基础笔试或者是技术一面

难度系数:中

面试题目:实现一个单链表的反转。例如:10  9   8   7   6   5   4   3   2   1

反转之后应为:1   2   3   4    5   6   7   8   9   10

要求10分钟之内写出代码,注意代码风格以及时间复杂度

考点分析

(1)基本概念:链表基础,代码规范问题,代码健壮性问题

(2)对时间复杂度敏感

 

解题思路:“一问,二画,三答”

 

其实对于这个问题,我们下面先给出解题思路的几种方式,来解释为什么要先问清楚(首先要问清楚面试官侧重的是什么)!!!

下面以角色的身份来阐述本问题的思路

 

1.小张

“我学过链表的基本操作,我可以重新申请一个链表,利用链表的前插法(头插法),这样就可以实现了链表的反转,我的思路是这样的。”

我重新从创建空表开始,一个一个将链表的结点插入到新开辟的链表的表头,也就是头结点之后,如下图看我的思路。

我还写好了算法了呢,看下面

LinkList ReverseList(LinkList &L){ //从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素 LNode *s;int x; L=(LinkList)malloc(sizeof(LNode)); //创建头结点 L->next=NULL; //初始为空链表 scanf("%d", &x); //输入结点的值 while(x!=9999) { //输入 9999 表示结束 s=(LNode*)malloc(sizeof(LNode) ); //创建新结点 s->data-x; s->next=L->next; L->next=s; //将新结点插入表中,L为头指针 scanf ("%d", &x); } //while 结束 return L;}

 

2.小杨

“是的,你上面的代码可以实现要求,不过,我觉得空间复杂度为比较大,我有一个方法,借助三个指针来实现,下面是我的思路”

上面是我的思路,下面是我的核心代码,代码和上面思路完全一样

LinkList reverse_link(LinkList list){ if (NULL == list || NULL == list->next) return list; LinkList temp ,preV,next; preV = list; temp = list->next; preV->next = NULL; while (temp != NULL) { next = temp->next; temp->next = preV; preV = temp; temp = next; } return prev;}

这个代码的时间复杂度为O(n),另外仅仅申请了两个变量来存储额外信息。

 

3.小糊涂

“我和你们的思路都不一样,你看看所有的都是后移后移,

如果我们把当前的结点逆序,我们先可以这样,把它的后继结点都逆序了,然后再把逆序好的尾结点的next指针再指向当前结点就好了吗”

这样就需要比较少的代码啦,在这个里面要注意一点递归出口,在这里我是把链表为空或者链表只有一个结点当作递归的出口,下面是我的代码,代码比较简洁

list *reverse(list *p, list *&head){ if(p == NULL || p->next == NULL) { head = p; return p; } else { list *temp = reverse(p->next, head); temp->next = p; return p; }}

 

4.小孙

上面利用递归操作(也是栈的应用),实际上可以很好的解决问题,我的思路也是利用栈操作,使用栈的先进后出特性,完成对链表的逆序输出。

下面是我的代码,思路大家看代码就会清楚

//逆向输出stack<int> reOutput(LinkNode *linkNode) {LinkNode *head;stack<int> s;head = linkNode;while (head != NULL) {s.push(head->value);head = head->next;}return s;}stack<int> s;s = reOutput(linkNode);while (!s.empty()) {cout << s.top() << endl;s.pop();}

通过上面先压栈,然后再出栈,自定义栈的大小,可以很好的解决问题,据听说,这是很多大公司采取的方案!!!

 

5.老师发言

当大家碰到这个题目的时候,首先要问明白这个出题人的思想,问清楚是否对链表做出限制

(1)如果说不能更改链表的结构,显然第二种方法就不行了,如果对链表的结构没有什么要求,这个方法还是很好的,毕竟时间复杂度为O(n),空间复杂度为常数S(1)

(2)如果数据比较繁多,虽然递归操作代码量比较少,但是可能会导致栈溢出(而且问题也比较难排查出),所以递归有这个风险,如果能克服这个风险,递归也是个不错的选择。

(3)假如有100w条数据,可能会导致栈溢出,我们可以利用栈操作,因为栈的特性是先进后出,所以就可以很好的解决了这个倒序问题,而且我们自定义栈,栈溢出,也被考虑到了。

(4)至于头插法,如果时间复杂度和空间复杂度不要求,应该是个比较容易理解的过程。

所以各有千秋,大家主要是了解思想,代码很好写。

 

, 1, 0, 9);

相关产品

COPYRIGHTS©2017 大班BET最新客服 ALL RIGHTS RESERVED 备案号:248