Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Example 1:

  1. Input: [3,2,3]
  2. Output: 3

Example 2:

  1. Input: [2,2,1,1,1,2,2]
  2. Output: 2

这是到求大多数的问题,有很多种解法,其中我感觉比较好的有两种,一种是用哈希表,这种方法需要 O(n) 的时间和空间,另一种是用一种叫摩尔投票法 Moore Voting,需要 O(n) 的时间和 O(1) 的空间,比前一种方法更好。这种投票法先将第一个数字假设为过半数,然后把计数器设为1,比较下一个数和此数是否相等,若相等则计数器加一,反之减一。然后看此时计数器的值,若为零,则将下一个值设为候选过半数。以此类推直到遍历完整个数组,当前候选过半数即为该数组的过半数。不仔细弄懂摩尔投票法的精髓的话,过一阵子还是会忘记的,首先要明确的是这个叼炸天的方法是有前提的,就是数组中一定要有过半数的存在才能使用,下面来看本算法的思路,这是一种先假设候选者,然后再进行验证的算法。现将数组中的第一个数假设为过半数,然后进行统计其出现的次数,如果遇到同样的数,则计数器自增1,否则计数器自减1,如果计数器减到了0,则更换下一个数字为候选者。这是一个很巧妙的设定,也是本算法的精髓所在,为啥遇到不同的要计数器减1呢,为啥减到0了又要更换候选者呢?首先是有那个强大的前提存在,一定会有一个出现超过半数的数字存在,那么如果计数器减到0了话,说明目前不是候选者数字的个数已经跟候选者的出现个数相同了,那么这个候选者已经很 weak,不一定能出现超过半数,此时选择更换当前的候选者。那有可能你会有疑问,那万一后面又大量的出现了之前的候选者怎么办,不需要担心,如果之前的候选者在后面大量出现的话,其又会重新变为候选者,直到最终验证成为正确的过半数,佩服算法的提出者啊,代码如下:

C++ 解法一:

  1. class Solution {
  2. public:
  3. int majorityElement(vector<int>& nums) {
  4. int res = , cnt = ;
  5. for (int num : nums) {
  6. if (cnt == ) {res = num; ++cnt;}
  7. else (num == res) ? ++cnt : --cnt;
  8. }
  9. return res;
  10. }
  11. };

Java 解法一:

  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. int res = 0, cnt = 0;
  4. for (int num : nums) {
  5. if (cnt == 0) {res = num; ++cnt;}
  6. else if (num == res) ++cnt;
  7. else --cnt;
  8. }
  9. return res;
  10. }
  11. }

下面这种解法利用到了位操作 Bit Manipulation 来解,将这个大多数按位来建立,从0到31位,每次统计下数组中该位上0和1的个数,如果1多,那么将结果 res 中该位变为1,最后累加出来的 res 就是过半数了,相当赞的方法,参见代码如下:

C++ 解法二:

  1. class Solution {
  2. public:
  3. int majorityElement(vector<int>& nums) {
  4. int res = , n = nums.size();
  5. for (int i = ; i < ; ++i) {
  6. int ones = , zeros = ;
  7. for (int num : nums) {
  8. if (ones > n / || zeros > n / ) break;
  9. if ((num & ( << i)) != ) ++ones;
  10. else ++zeros;
  11. }
  12. if (ones > zeros) res |= ( << i);
  13. }
  14. return res;
  15. }
  16. };

Java 解法二:

  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. int res = 0, n = nums.length;
  4. for (int i = 0; i < 32; ++i) {
  5. int ones = 0, zeros = 0;
  6. for (int num : nums) {
  7. if (ones > n / 2 || zeros > n / 2) break;
  8. if ((num & (1 << i)) != 0) ++ones;
  9. else ++zeros;
  10. }
  11. if (ones > zeros) res |= (1 << i);
  12. }
  13. return res;
  14. }
  15. }

Github 同步地址:

https://github.com/grandyang/leetcode/issues/169

类似题目:

Majority Element II

参考资料:

https://leetcode.com/problems/majority-element/

https://leetcode.com/problems/majority-element/discuss/51613/O(n)-time-O(1)-space-fastest-solution

https://leetcode.com/problems/majority-element/discuss/51612/6-Suggested-Solutions-in-C++-with-Explanations

https://leetcode.com/problems/majority-element/discuss/51611/Java-solutions-(sorting-hashmap-moore-voting-bit-manipulation).

https://leetcode.com/problems/majority-element/discuss/51828/C++-solution-using-Moore's-voting-algorithm-O(n)-runtime-comlexity-an-no-extra-array-or-hash-table

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Majority Element 求众数的更多相关文章

  1. [LeetCode] Majority Element 求大多数

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  2. 169. Majority Element求众数

    网址:https://leetcode.com/problems/majority-element/ 参考:https://blog.csdn.net/u014248127/article/detai ...

  3. 169 Majority Element 求众数 数组中出现次数超过一半的数字

    给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素.你可以假设数组是非空的,并且数组中的众数永远存在. 详见:https://leetcode.com/p ...

  4. 2016.5.18——leetcode:Majority Element

    Majority Element 本题收获: 1.初步了解hash,nth_element的用法 2.题目的常规思路 题目: Given an array of size n, find the ma ...

  5. [LeetCode] Majority Element II 求众数之二

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  6. [LeetCode] Majority Element II 求大多数之二

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. Note: The a ...

  7. LeetCode 169. Majority Element (众数)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  8. ✡ leetcode 169. Majority Element 求出现次数最多的数 --------- java

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  9. [LintCode] Majority Number 求众数

    Given an array of integers, the majority number is the number that occurs more than half of the size ...

随机推荐

  1. 野路子出身PowerShell 文件操作实用功能

    本文出处:http://www.cnblogs.com/wy123/p/6129498.html 因工作需要,处理一批文件,本想写C#来处理的,后来想想这个是PowerShell的天职,索性就网上各种 ...

  2. Lua BehaviourTree 各节点说明

    项目说明 本行为树的代码使用Lua编写,所有的内容也建立的Lua的基础语法之上 因为公司项目需求,需要一套Lua的行为树代码,所以尝试从饥荒中抽离了行为树相关的代码.绝大多数节点行为与饥荒中相同,不过 ...

  3. ThreadPool.QueueUserWorkItem的用法

    代码: ThreadPool.SetMaxThreads(, ); ThreadPool.QueueUserWorkItem((obj) => { MessageBox.Show("执 ...

  4. 【无私分享:ASP.NET CORE 项目实战(第五章)】Repository仓储 UnitofWork

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 本章我们来创建仓储类Repository 并且引入 UnitOfWork 我对UnitOfWork的一些理解  UnitOfW ...

  5. 【Oracle基本操作1】 数据库的新建删除

    一.新建数据库 1.新建数据库. 1.1打开 Database Configuration Assistant  : 1.2选择新建数据库,下一步,选第一个"一般用途或事物处理": ...

  6. 使用 jQuery Ajax 在页面滚动时从服务器加载数据

    简介 文本将演示怎么在滚动滚动条时从服务器端下载数据.用AJAX技术从服务器端加载数据有助于改善任何web应用的性能表现,因为在打开页面时,只有一屏的数据从服务器端加载了,需要更多的数据时,可以随着用 ...

  7. 什么是WebPack,为什么要使用它?

    1.什么是Webpack WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等) ...

  8. AngularJS下对数组的比较

    Javascript不能直接用==或者===来判断两个数组是否相等,无论是相等还是全等都不行,以下两行JS代码都会返回false <script type="text/javascri ...

  9. SAP GUI的配置文件

    GUI是SAP系统最常用的客户端,在一台客户机上,利用GUI可以连接多套SAP系统(连接方法参见<客户端连接配置(SAP GUI 710)>),也可以设置多个快捷方式登录(参见<用快 ...

  10. 一些Titanium学习的地方

    利用titanium兑现外汇兑换计算的ios代码   http://rensanning.iteye.com/blog/1325011 Titanium兑现相关的报表功能   http://www.s ...