渣基础:比照Hawstein学Cracking the coding interview(4)

作者:Hawstein
出处: http://hawstein.com/posts/2.1.html

声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处。


Q2.1  从一个未排序的链表中移除重复的项进一步地,如果不允许使用临时的缓存,你如何解决这个问题?

方法一:作者提到了哈希表,不会用。。。  维基百科  http://zh.wikipedia.org/wiki/%E5%93%88%E5%B8%8C%E8%A1%A8

方法二:对比作者的方法,我自己的代码还是需要注意健壮性!  比如 head==null 的时候,直接return这种容易漏过去。。。

还有就是记得要delete这个空间,不只是更改下链表的前后关系。

Q2.2  实现一个算法从一个单链表中返回倒数第n个元素。

方法一:“这个次序颠倒的思路可以让我们联想到一种数据结构:栈。”  作者想到了 栈,然后联想到了递归是天然的栈。

我们如果遍历一遍单链表,将其中的元素压栈,然后再将元素一一出栈。那么, 第n个出栈的元素就是我们想要的。


那我们是不是需要显式地用栈这么一个结构来做这个问题呢?答案是否。看到栈,我们应当 要想到递归,它是一种天然使用栈的方式。所以,第一种解决方案用递归,让栈自己帮我 们从链表的最后一个元素数起。


思路很简单,如果指向链表的指针还未空,就不断递归。当指针为空时开始退递归,这个过 程n不断减1,直接等于1,即可把栈中当前的元素取出。


很棒的一种思路,灵活运用数据结构啊。。。


方法二:

虽然我们没办法从单链表的最后一个元素往前数,但如果我们维护两个指针, 它们之间的距离为n。然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变。那么,当第二个指针指到空时,第一个指针即为所求。很tricky的方法, 将这个问题很漂亮地解决了。


Q2.3 实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针。
例子:
输入:指向链表a->b->c->d->e中结点c的指针
结果:不需要返回什么,得到一个新链表:a->b->d->e


这题没有给出头指针,这样的话,就不能直接搜了,也就是说只能得到c以后的链表,这样的话,由于链表里的结构是类似的,直接删除下一个,把值附好就行了。

这里Hawstein提到了程序的健壮性问题,也就是要注意各种情况,比如如果c指向链表的:1.头结点;2.中间结点。 3.尾结点。4.为空。

“情况1,2属于正常情况,直接将d的数据给c,c的next指针指向d 的next指向所指结点,删除d就OK。情况4为空,直接返回。情况3比较特殊,如果c 指向尾结点,一般会认为直接删除c就ok了,反正c后面也没有结点了,不用担心链表断开。 可是真的是这样吗?代码告诉我们,直接删除c,指向c的那个结点(比如说b)的next指针 并不会为空。也就是说,如果你打印这个链表,它还是会打印出和原来链表长度一样的链表, 而且最后一个元素为0!“



关于这一点,原书CTCI中是这么讲的,这正是面试官希望你指出来的。然后, 你可以做一些特殊处理,比如当c是尾结点时,将它的数据设置为一些特殊字符, 这样在打印时就可以不打印它。当然也可以直接不处理这种情况,原书里的代码就是这么做 的。这里,也直接不处理这种情况。”

你可能感兴趣的:(C++,Cracking,the,coding,interview)