LeetCode 1

    由题目要求的时间复杂度log(m+n)知不能遍历求解,必须采用二分法以压缩时间。每一次循环要尽量使范围缩小一半。而因为列表已经排好序,所以确定列表中一个元素的值,就能确定所有元素的范围。以此为基础,我构建了如下算法:
    设两个列表的长度分别为L1、L2,其中L1>L2。求出分别的中位数M1、M2,若M1>M2,则L1中所有M1以后的元素都大于M2,而L2中所有M2之前的元素都小于M1。可得,所求中位数的值应在M1到M2之间。所以,设N<L2/2,则同时删去L1的最后N个数和L2的最前N个数,对所求的中位数无影响。该操作每一次都会使较短列表长度减半,而当其长度减小到一定时(如2以内),就可以相对容易地求出总中位数的值。循环此操作,即可满足二分的要求。
    因为当数列长度为偶数时,中位数是其中间两个数的平均值。所以上述操作的临界条件是短列表长度小于等于2。没有必要真正删去列表中的数,只需用变量记录其首尾序号,并改动它即可。最后,当达到临界条件后,将长列表中间若干个元素拿出,和短列表中元素组合成一个新列表。此列表的中位数即为所求。
    本题的方法其实并不复杂,但实现起来比较恶心,花费了我两个小时。主要原因一是平时都用C++做算法题,对Python的种种格式和操作还不太熟悉,查阅资料花费了一定时间。二是题中的越界检查和特殊情况(如列表为空)需要仔细考虑,额外花费不少时间。
    我实现的步骤较为简单,但用时相对较长,高出平均,这主要是因为不想在最后分类讨论,就用了费时的sort函数和列表切片方法,以求方便。代码如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值