分析“找出整形数组中占比超过一半的数”|豆包MarsCode AI刷题

87 阅读5分钟

一、题目解析

思路

这道题可以采用多种方法来解决。一种常见的思路是利用投票算法(摩尔投票法),其核心原理是不同的数相互抵消,最后剩下的那个数有可能就是占比超过一半的数,因为它的出现次数足够多,能在抵消过程中留存下来。另外,也可以先通过字典来统计数组中每个数出现的次数,然后遍历字典找到出现次数超过数组长度一半的那个数。

代码详解(以摩尔投票法为例)

python

def find_majority_element(nums): candidate = None count = 0 for num in nums: if count == 0: candidate = num count = 1 elif candidate == num: count += 1 else: count -= 1 return candidate

nums = [1, 2, 1, 1, 3, 1] print(find_majority_element(nums))  

在上述代码中,首先初始化候选数  candidate  为  None  ,计数  count  为0。然后遍历整型数组  nums  ,当  count  为0时,将当前数字设为候选数并把  count  置为1;如果当前数字和候选数相同,就把  count  加1;要是不同,就把  count  减1。最后返回的  candidate  就是可能占比超过一半的数(还需要再验证一下其出现次数确实超过数组长度一半,这里只是核心逻辑代码)。

二、知识总结

新知识点

  • 摩尔投票法:学习到了这种巧妙的通过抵消来筛选出可能的多数元素的算法,理解了它在处理这类找出现次数占优元素问题上的优势。
  • 算法复杂度分析:体会到摩尔投票法时间复杂度为 O(n) ,空间复杂度为 O(1) ,相较于用字典统计(时间复杂度 O(n) ,空间复杂度 O(n) )在空间利用上更高效,能更深入理解不同算法复杂度在实际应用中的体现。

理解

  • 摩尔投票法的关键在于利用多数元素出现次数多于其他元素总和这一特点,通过不断抵消来凸显它,要把握好计数增减和候选数更新的时机。而用字典统计相对更直观,是常规的统计出现次数思路,但在空间上可能消耗更多,尤其在数据量很大时。

学习建议

  • 对于摩尔投票法,要多通过不同示例数组去实践体会,深入理解其抵消过程以及边界情况的处理,比如数组中只有一种元素或者元素分布很均匀的情况。对于算法复杂度分析,要养成习惯去分析自己写的代码或者学习的算法的复杂度,对比不同算法复杂度差异带来的性能变化。

三、学习计划

刷题计划制定

  • 可以集中练习类似找多数元素、找出现次数满足特定条件元素的题目,每天安排几道,先从简单数组情况开始,再逐步过渡到复杂一些的,比如二维数组里找多数元素等情况。每做完一周的题目后进行总结回顾,梳理不同解法的优缺点以及适用场景。
  • 除了Python实现,也可以尝试用其他编程语言去实现相同的算法思路,加深对算法本身的理解,不受限于语言语法特点。

利用错题进行针对性学习

  • 把做错的这类题目整理出来,分析是算法思路没掌握好,还是代码实现细节出了问题,比如摩尔投票法里计数增减逻辑写错等情况。
  • 针对薄弱点,找更多同类型的题目强化练习,若是算法思路问题,就重新学习相关算法原理,结合正确示例代码对比分析自己的错误;若是代码实现细节,就多做几遍同类代码实现,注意易错点。

四、工具运用

与在线课程相结合

  • 查找讲解算法基础、Python数据结构与算法相关的在线课程,学习课程中关于投票算法等找多数元素的原理讲解以及示例演示,然后再到这道题里实践运用。
  • 遇到不懂的地方,比如摩尔投票法的数学证明或者更复杂变形情况,可以通过在线课程的答疑区或者评论区请教老师和其他同学,加深理解后再回头完善自己对此题的解法。

与学习论坛相结合

  • 在学习论坛上分享自己对于这道题的解题思路和遇到的问题,看看其他同学有没有不同的见解或者更好的解法,比如可能有基于排序后取中间元素的巧妙思路(在特定情况下适用)等,相互交流学习。
  • 关注论坛上一些大神分享的关于数组元素统计分析相关的算法总结、代码优化技巧等帖子,汲取经验运用到自己后续的学习和解题中。

与纸质书籍相结合

  • 翻阅Python编程书籍里关于算法实现、数据结构运用章节,参考书中标准规范的代码写法以及对类似问题更深入的理论分析,比如对算法时间空间复杂度更严谨的推导等。
  • 把从纸质书籍中学到的知识,比如更优化的代码结构、新的解题思路等,运用到实际解答这道题以及同类型题目的过程中,不断提高自己的编程和解题能力。