==============
版权声明:由于公众号后台规则问题,本文暂时无法设置原创标记,但仍属原创内容,微信公众号“Python小屋”坚持只发原创技术文章。
=============
推荐图书:
董付国著,《Python程序设计基础(第3版)》(微课版),ISBN:9787302611035,清华大学出版社,定价59.8元,2023年1月出版,2024年3月第7次印刷(本书前两版累计印刷27次,已退出历史舞台),全国高等学校计算机教育研究会“十四五”规划教材,山东省高等教育优秀教材,山东省普通高等教育一流教材,山东省一流本科课程“Python应用开发”(线上线下混合)配套教材,山东省一流本科课程“Python程序设计基础”(线上)配套教材,清华大学出版社2019、2020、2021、2022、2023年畅销教材
图书内容:Python基础,正则表达式,文件操作,数据库操作,数据分析与科学计算可视化
配套慕课:中国大学MOOC、智慧树,搜索“董付国”
配套微课:43小时
配套资源:教学大纲、课件、源码、数据文件、在线练习软件
页数:310
适用专业:非计算机专业(偏理科)、选修课
适用层次:研究生/本科/专科
适用学时:48/64
配套资源:用书教师可以免费获取教学大纲、教案、课件、源码、习题答案、慕课、在线练习与考试系统。
==============
问题描述:计算给定列表的逆序数,也就是每个元素后面比它小的元素数量之和。
(1)对于这个问题,直接使用两层循环即可实现,代码也很简洁。
但是,从算法设计与优化的角度来讲,我们从来不以代码行数多少来判断其优劣。上面的代码虽然简洁,但时间复杂度是平方级的O(n^2),毫无技巧可言,实在算不上是个好的算法。
(2)参考归并排序算法中使用的分治法,这个问题的求解算法时间复杂度可以达到O(nlogn)。改进算法的核心思路为:1)把列表L平均分为前半部分A和后半部分B;2)统计前半部分A的逆序数和后半部分B的逆序数,以及满足a>b的(a,b)个数,其中a属于A且b属于B,统计逆序数的同时把A和B分别排序并合并为一个列表;3)对前后两部分重复上面的操作。这样以来,在合并A和B时由于已经排序,只需要从前向后扫描A和B,把小的元素移出并添加到结果列表中,如果B最前面的元素小则把逆序数增加A中元素的数量(此时A中所有元素都大于B的第一个元素)。
考虑到Python列表在删除前面元素时会导致后面元素向前移动而引入额外开销,下面的代码并没有真正移出元素,而是通过下标向后移动来模拟移出元素,避免了额外的时间开销。
(3)下面代码把逆序数和插入排序算法结合起来,从后向前扫描元素,每个元素向后移动至合适位置使得原位置后面的元素降序排列,插入位置后面元素数量也就是该元素的逆序数。逆序数越大,下面的算法优势越明显。原始数据恰好降序排列时效率高于前面的两种算法,但原始数据为升序排列时效率非常低,平均效率略高于前面的count()函数但远低于前面的sort_count()函数。
(4)编写代码,测试三种方法的效率
数据完全升序排列的情况:
运行结果:
测试数据完全降序排列的情况:
运行结果:
测试随机数据的情况:
运行结果:
=================
温馨提示:
关注微信公众号“Python小屋”,在公众号后台发送消息“大事记”可以查看董付国老师与Python有关的重要事件;发送消息“教材”可以查看董付国老师出版的Python系列教材(已累计印刷超过200次)的适用专业详情;发送消息“历史文章”可以查看董付国老师推送的超过1300篇原创技术文章;发送消息“会议”可以查看近期董付国老师的培训安排;发送消息“微课”可以查看董付国老师免费分享的超过700节Python微课视频;发送消息“课件”可以查看董付国老师免费分享的Python教学资源;发送消息“小屋刷题”可以下载“Python小屋刷题神器”,免费练习3857道客观题和757道编程题,题库持续更新;发送消息“编程比赛”了解Python小屋编程大赛详情。