您的位置:首页 > 职场人生

看大神文章小结——微软等面试7,8

2013-04-27 11:43 225 查看
大神 地址 :http://blog.csdn.net/v_JULY_v/article/details/6015165

第 7 题(链表)

微软亚院之编程判断俩个链表是否相交

给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交。

为了简化问题,我们假设俩个链表均不带环。

问题扩展:

1.如果链表可能有环列?

2.如果需要求出俩个链表相交的第一个节点

考虑思路 首先 想到的可能是循环一个个找 找到想同的就可以了。可是 仔细相一下。 既然只需要判断是否相交。 如果一旦相交 是不是最后都会指向同一个节点? 所以 只要判断最后一个节点是否相同就可以了。

这个代码太简单 就不写了。 接下来是问题扩展

1: 这个也好解决。如果环链相交 那么这2个链表 就会一模一样。 所以 在第一个循环找尾部的时候 没找到一个 判断一下当前节点是
不是第一个节点。 如果是第一个节点 就是环链。如果不是 一直到最后一个节点 就不是环链。然后在遍历第二个链表。如果是环链 就和第一个链表的第一个元素比较。相同就相交 一直到最后一个。代码也简单。不写了。

2:扩展2 有点意识了。需要的是第一个节点。之前的思路很明显 不行了。如果是双向链表 还可以用第一个思路 然后往回找。如果可以用额外的空间的话。 我会遍历链表的时候。加上一个栈。 2个栈 一起出栈 只到不等为止。 这个思路很简单 代码也很简单。 如果不可以这样用额外的空间的话。 我想 我只会利用2个循环 慢慢遍历了。

然后 看了一下别人的文章 发现自己想当然了。思路大体是不错的。错就错在“带坏”上面。 没能理解。 因为环链不一定是头尾相连。可能显示一条直线 然后在环的。

再想想解决方案::

如何判断是环链呢?只要找到环的起点就可以了。 因为一旦相交环形部分肯定相同。思路用上面的就可以了。我自己的想法还是需要遍历的时候 在跟已经遍历过的节点一个个比较。 有相同的就是环链 。没有一直到尾部不是环链。看了大神的答案 发现别人的思路真好。 循环的时候取的步长不同。一个取1,一个取2.那么如果环链很快就会相遇。只要相遇。 获取那个节点。把遍历第二个链表是否存在这个节点(最好也做一下 是否环链判断。 如果一个是环链 一个不是
铁定不想交。 而且环链会死循环,所以要在判断是否环链的时候记录下一个环上面的节点 用作跳出循环。)

第9题

-----------------------------------判断整数序列是不是二元查找树的后序遍历结果

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。

如果是返回 true,否则返回 false。

例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:

8

/ \

6 10

/ \ / \

5 7 9 11

因此返回 true。

如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false。

//貌似,少有人关注此题。:).2010/10/18

这个题 一看就有思路。可是思路也很模糊。 看到题目 第一个想法就是 既然这个序列是 后续遍历的结果那么久应该可以还原那个树。 所以 这道题就是 判断这个序列能不能还原成一棵树。 首先明白什么事后续。 就是 左节点 右节点 根节点

首先考虑 每一个节点的情况。如果这个节点是 左节点。 那么 后面 的树比他大 就是他的兄弟右节点。 如果比他小 就是他的父节点。 如果他是右节点。那么只能比他小。按照这个思路做下去。 等于是分成 一个数 或者 2个数 或者3个数 为一个整体 合并成一个数 最终一直合并到根节点。 如果能合并起来就是对的。

尝试着想了一下 貌似 不怎么好想。 可能思路不对。 决定换个思路。 不从前开始遍历。从后面呢? 后面的肯定都是根节点啊。这样应该会简单一点吧?

思路是这样的。 从后向前遍历。 越到的第一个数肯定是跟节点。 然后 在这个数组的前半部分 必须是比根节点小。剩下的肯定比根节点大。然后分成2个子数组。递归调用。能够顺利完成 就是对的。这个思路应该明确很多。实际上 思考数的任何问题 感觉都应该围绕根节点来思考。

解决了问题 小小测试了一下 貌似没有问题 核心代码如下

private boolean checkTree(List<Integer> dataList ){
int rootNum=dataList.get(dataList.size()-1);
if(dataList.size()<3){
return true;
}
boolean isLeft=true;
int index=-1;
for(int i=0;i<dataList.size()-1;i++){
if(!isLeft && dataList.get(i)<rootNum){
return false;
}else	if(dataList.get(i)>rootNum){
isLeft=false;
index=i;
}
}
boolean checkLeft=true;
boolean checkRight=true;
if(index==-1){
checkLeft=checkTree(dataList.subList(0, dataList.size()-1));
}else{
checkLeft=checkTree(dataList.subList(0, index));
checkRight=checkTree(dataList.subList(index, dataList.size()-1));
}
return checkLeft&&checkRight;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: