首页 新闻 会员 周边

一个比较重复项问题

0
悬赏园豆:5 [已解决问题] 解决于 2012-10-12 20:43

比较两张字符串单链表 查找其中是否有重复值 数据量很大但可以构建Hash 现在有三种解决方案 第一是双重循环遍历判断是否有重复项 第二是将第一张表构建成HashTable 遍历第二张表判断HashTable内位置有没有被占 第三是把第二张表也压入同个HashTable内直到返回重复位置提示 假设算法不会产生冲突 我想问是不是后两种方法效率比第一种更低?

林J的主页 林J | 菜鸟二级 | 园豆:202
提问于:2012-10-11 09:05
< >
分享
最佳答案
0

后两种方法要判断有没有被占的,这个判断其实也做了遍历,所以归根结底都是双重循环遍历。

更好的方法:先统计一下两个链表中的节点个数,记为sum。

然后将两个链表头尾拼接起来成为一个环,随便取一个节点记为a

由a向同一方向做两种遍历,一种每次往前一个节点,另一种每次往前两个节点,并判断这两种所取节点值是否相同

如果值相同再看遍历的次数是否小于sum,如果小于sum说明有重复项

收获园豆:5
田林九村 | 老鸟四级 |园豆:2367 | 2012-10-11 09:16

谢谢。

林J | 园豆:202 (菜鸟二级) | 2012-10-11 09:23

@林J: 客气

田林九村 | 园豆:2367 (老鸟四级) | 2012-10-11 09:23

@田林九村: 想明白了,虽然同样是要遍历,但是第一种的时间复杂度是O(n2),后面是O(2n)还是后面的好

林J | 园豆:202 (菜鸟二级) | 2012-10-11 09:44

@林J: 错了,都是O(n2)

田林九村 | 园豆:2367 (老鸟四级) | 2012-10-11 10:11

@田林九村: 用Hash表肯定是2n啊,双重遍历n²没问题,Hash表的话第一张表构建成hash表位n,第二张表只要遍历每个项的HashCode,查看是否已经存在就行了,不需要再遍历第一张表,所以只要2n,假设两张表的长度都是n.

林J | 园豆:202 (菜鸟二级) | 2012-10-11 10:15
其他回答(1)
0

题目跟楼上说的好像都没大明白,判断重复项是看两个链表中有没有相同的?如果是这样的话,楼上说的那个方法没想明白原理是什么。

顾晓北 | 园豆:10844 (专家六级) | 2012-10-11 09:42

一种是每次往前两个,一种是每次往前一个,这样当往前一个的遍历一圈时往前两个的就遍历了两圈,这个时候两个值肯定是相同的--因为都回到了起点a。

如果遍历的次数小于sum就遇到相同的值时。

有两个结论:

首先两种遍历当前不可能在同一个节点(这个仔细想一下就明白了)

其次说明还没有遍历完就遇到相同的了

这样就证明了有重复值

支持(0) 反对(0) 田林九村 | 园豆:2367 (老鸟四级) | 2012-10-11 10:09

@田林九村: 那这个问题解决了吗?

1.如果两个链表拼在一起的项数是偶数,那么每次往前移动两次的那个可以遍历到的只能是拼接起来以后的环中的一半元素吧?

2.看一下最后每个节点跟其他元素比较了几次?拿a节点来说吧,跟其他节点比较了几次?两次?这样可以保证a节点有跟比较这两次之外的元素重复吗?

支持(0) 反对(0) 顾晓北 | 园豆:10844 (专家六级) | 2012-10-11 10:19

@田林九村: 这里表述有问题,首先这个是两个单链表,头尾相连的话,会形成一个大环,但是当它们当中有相同项时,大环中间还会有一个小环,此时大环的项是不可能全部遍历到的,即这个环内节点总数会小于两个单链表节点总数之和。

这个时候再计算,就是环链表的问题了。使用一个前进一步,一个前进两步的方式,在环链表中有一个概念是:两个点在任意相同或不同位置出发,向一个方向移动,它们最终相遇的时间单位肯定小于等于环的节点数,而最大单位时间就是在它们于同一点出发时。这是个数学问题。得出的结论就是:当存在环结构时,遍历的最大长度肯定小于两个链表的节点数。

支持(0) 反对(0) 林J | 园豆:202 (菜鸟二级) | 2012-10-11 10:28

@林J: 可能是我数学不太好,还是没大懂这个意思。两个链表首尾连接成为一个大环,里面还有一个小环是什么意思?“这个环内节点总数会小于两个单链表节点总数之和。”这其中的“这个环”是你说的拼接以后的大环吗?如果是,他的节点总数小于两个单链表节点总数之和?为什么?

 

还是拿一个例子吧:假设有1,2,3,4和5,6,7,8两个单链表,拼接以后是1,2,3,4,5,6,7,8,一个环,就拿1节点开始,那么就是1跟2,比较,2跟4比较,这样的话,每次前进两个节点的那个循环可以访问到的节点就是2,4,6,8,另外四个根本就访问不到,这是我上面说的第一个问题。

第二个问题,循环1进行了一圈,循环2进行了两圈,那么最终下来,结果是偶数节点跟其他节点有两次比较,奇数节点有一次比较,结果是这样吧?如果是这样,那得到的结果正确吗?

支持(0) 反对(0) 顾晓北 | 园豆:10844 (专家六级) | 2012-10-11 10:59

@顾晓北: 你上面说的情况是只有一个大环,这种情况是会回到起点,说明没有重复点。

所谓的会有小环,比方说一个是1,2,3,4,5,6,7,另外一个是8,9,10,11,4,5,6.只要出现4,它的指针肯定会指向5,所以合并以后是1,2,3,4,5,6,7,8,9,10,11->4 在11这里开始形成环。小环就是4,5,6,7,8,9,10,11组成的。

支持(0) 反对(0) 林J | 园豆:202 (菜鸟二级) | 2012-10-11 11:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册