查看: 3658| 回复: 27
收起左侧

[二分/排序/搜索] 在两个排序的list中找全部相同元素

knkm 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   756
98%
2%
12

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x

面试题
给两个排序的list,A和B,找出A和B中全部的相同元素。
len(A) = n
len(B) = m
m >> n
Integer.MIN_VALUE <= A[i] <= Integer.MAX_VALUE
Integer.MIN_VALUE <= B[i] <= Integer.MAX_VALUE


eg
[1,2,3,4,5] [1,3,5,8] return [1,3,5]


我觉得是没有log复杂度的解法,最好只能是m+n,如果m>>n 可能nlogm会更优,别的都是细节上调一调了,复杂度是不可能更好的。
面的时候一直想说不可能比线性复杂度更好,我看他一直叫我优化我也不知道该不该说不可能,估计面试挂了。
面的时候我一直在想二分缩小范围来想办法让它log复杂度,事后仔细想想,就算写出来了也是线性复杂度的。
唉,就这样吧,没想到终面是这样的。


不知道有没有别的log的解法或者更快解法。



补充内容 (2024-10-16 13:37 +08:00):

分享我的code,当然面试的时候出了错,不过这个并不是log复杂度,最坏情况一样很垃。


if __name__ == '__main__':
    A = [1, 2, 3, 4, 4, 8]
    B = [0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 10]
    import bisect
    n = 0
    m = 0
    ans = []
    while n < len(A) and m < len(B):
        m = bisect.bisect_left(B, A[n], m)
        n = bisect.bisect_left(A, B[m], n)
        if n < len(A) and m < len(B) and A[n] == B[m]:
            ans.append(A[n])
        m+=1
        n+=1
    print(ans)

上一篇:min movements to move products
下一篇:分享最近遇到区间型 DP 的解题思路(为了赚到 188 大米看文章)
跳槽专家 2024-10-17 05:14:11 | 显示全部楼层
本楼:   👍  1
100%
0%
0   👎
全局:   3713
96%
4%
169
本帖最后由 跳槽专家 于 2024-10-16 21:29 编辑

这问题确实很搞笑,因为正常的解决思路就是俩set或者俩map互相比较。如果非得钻二分查找,那又要掰扯n必须是 log n*m的长度才是最优解,如果那句话说错或者面试官根本想的不是这个,那就踩马蹄子上啦。真是无语。挂了也没办法,这种题纯粹猜闷。
回复

使用道具 举报

JobOffer123 2024-10-17 03:23:23 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   108
98%
2%
2
我感觉time complexisty 是 Nlog(logM), 因为我们还是要遍历数组n,只是每次的M长度减半。
(不过gpt 说是 O(logM⋅logN),考虑到这不是第一次它胡说八道了,也就不继续调查了。FYI)
另外可能有bug,懒得调了。
  1. def getSameElement(m, n):
  2.     ans = []

  3.     def helper(lst1, start1, end1, lst2, start2, end2):
  4.         if start1 > end1: return

  5.         # binary search
  6.         m1 = start1 + (end1 - start1) // 2
  7.         m2 = binarySearch(lst2, start2, end2, lst1[m1])
  8.         if lst1[m1] == lst2[m2]:
  9.             ans.append(lst1[m1])
  10.             helper(lst1, start1, m1-1, lst2, start2, m2-1)
  11.             helper(lst1, m1+1, end1, lst2, m2+1, end2)
  12.         else:
  13.             helper(lst1, start1, m1-1, lst2, start2, m2)    # not m2-1
  14.             helper(lst1, m1+1, end1, lst2, m2+1, end2)


  15.     def binarySearch(lst, start, end, target):
  16.         l, r = start, end
  17.         while l <= r:
  18.             m = l + (r-l) // 2
  19.             if lst[m] < target: l = m + 1
  20.             elif lst[m] > target: r = m - 1
  21.             else: return m

  22.         return r


  23.     # left half, left half, right half, right half
  24.     helper(m, 0, len(m)-1, n, 0, len(n)-1)
  25.     return ans

  26. print(getSameElement([1,2,3,4,5],[1,3,5,8]))
复制代码
回复

使用道具 举报

 楼主| knkm 2024-10-16 13:25:35 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   756
98%
2%
12
本帖最后由 knkm 于 2024-10-16 01:40 编辑

给个code吧,面试的时候没写出来 ,平常用Java刷题的想用bisect省事,结果忘记了lo=?
时间复杂度 O(m+n)
空间复杂度 O(1)

if __name__ == '__main__':
    A = [1, 2, 3, 4, 4, 8]
    B = [0, 1, 2, 3, 4, 4, 4, 5, 6, 7, 10]
    import bisect

    n = 0
    m = 0
    ans = []
    while n < len(A) and m < len(B):
        m = bisect.bisect_left(B, A[n], m)
        n = bisect.bisect_left(A, B[m], n)

        if n < len(A) and m < len(B) and A[n] == B[m]:
            ans.append(A[n])
        m+=1
        n+=1


    print(ans)

评分

参与人数 1大米 +1 收起 理由
337845818 + 1 bisect_left不算时间奥?

查看全部评分

回复

使用道具 举报

zys87126 2024-10-16 10:48:44 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   770
98%
2%
16
List 有没有duplicate?
回复

使用道具 举报

 楼主| knkm 2024-10-16 10:50:54 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   756
98%
2%
12
zys87126 发表于 2024-10-15 22:48
List 有没有duplicate?

可有可无,没有指定
回复

使用道具 举报

sun090807 2024-10-16 11:02:15 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   1036
95%
5%
50
把b的元素在sorted的a里bs,如果无重复元素的话.
回复

使用道具 举报

 楼主| knkm 2024-10-16 11:07:47 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   756
98%
2%
12
sun090807 发表于 2024-10-15 23:02
把b的元素在sorted的a里bs,如果无重复元素的话.

这样是mlogn,比nlogm还差
并不是log解法啊
回复

使用道具 举报

sun090807 2024-10-16 11:35:40 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   1036
95%
5%
50
knkm 发表于 2024-10-15 20:07:47
这样是mlogn,比nlogm还差
并不是log解法啊
说反了,ab换一下,m>>n时候 mlgn <<m+n

评分

参与人数 1大米 +1 收起 理由
pandasum + 1 赞一个

查看全部评分

回复

使用道具 举报

vincent_great 2024-10-16 12:02:42 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   410
96%
4%
19
在b的里面二分找a的元素吧。。。
nlogm的时间这样。。
回复

使用道具 举报

rymwer 2024-10-16 12:29:25 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   8514
86%
14%
1330
本帖最后由 rymwer 于 2024-10-15 21:36 编辑

未必是让你优化时间, 这题空间可以优化到o(1)。 而且最好的做法,时间复杂度在 n 和 m
+ n之间, 如果你的解放是单纯的m + n 确实可以优化。

而且一般情况下,要主动比较nlogm 和m+ n的大小, 说明什么情况mlogn更小,什么情况 m + n 更小
回复

使用道具 举报

 楼主| knkm 2024-10-16 13:05:48 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   756
98%
2%
12
本帖最后由 knkm 于 2024-10-16 01:26 编辑
rymwer 发表于 2024-10-16 00:29
未必是让你优化时间, 这题空间可以优化到o(1)。 而且最好的做法,时间复杂度在 n 和 m
+ n之间, 如果你 ...

三种办法
最垃圾的HashMap 时间O(m+n) 空间O(n)
双指针 时间O(m+n) 空间O(1)
二分查找 时间O(nlogm) 空间 O(1)

应该不会有别的方法了,就算有也是根据以上方法进行稍微调整。
我和面试官说的通过两次二分查找缩小查找范围,时间复杂度也是就是先在B查A[0]然后查到后在A差B[i]但是仔细想想时间复杂度也是一样的,没啥变化 (就是改进双指针)。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

Advertisement
>
快速回复 返回顶部 返回列表