Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  1. How many majority elements could it possibly have?
  2. Do you have a better hint? Suggest it!

【题目分析】

在Majority Element中我们使用了一个巧妙的算法就是Moore's alogoirthm,在上一个题目中我们寻找的是the elements that appear more than ⌊ n/2 ⌋ times。

假设⌊ n/2 ⌋ = k,那么n最大值为2k+1,Majority Element至少为k+1个,因此Majority Element最多只能有一个。我们设置两个变量 ME 和count,ME用来存储当前的Majority Element,count对当前ME进行计数,计数规则如下。遍历数组,如果count = 0,则把当前元素赋给ME;否则的话如果当前元素=ME,则count++,否则count--;这个过程结束和,最后的EM肯定是我们Majority Element。

那么对于当前题目,设⌊ n/3 ⌋ = k,那么n最大为3k+2。如果有这样的元素它出现的个数大于k,那么这样的元素最多有两个(3k+2-2k-2 = k)。我们是否还可以用Moore's alogoirthm来解决我们的问题呢?

因为最多只能有两个Majority Element,我们设置如下几个变量:EM1,EM2,count1,count2,用来表示两个Majority Element和他们的计数。我们讨论一下下面几种情况:

1. 不存在Majority Element。那么我们最后会得到一个结果,但是这个结果可能是不正确的,需要重新遍历一次数组来对找到的元素进行计数;

2. 存在两个Majority Element。我们知道 count(EM1) >= k+1, count(EM2) >= k+1,剩余的数字 count(remain) <= k。遍历数组的过程中,如果当前元素和EM1,EM2都不相同,那么count1--,count2--,最后的结果肯定是Majority Element,因为他们的数目比其他元素多,count数不会被减到0;

3. 存在一个Majority Element。此时count(EM1) >= k+1,那么在算法执行的过程中EM1是否会被减到0呢?比如k+1个EM1出现在数组的最前面,在遍历到其他数字时,由于count(remian)<= 2k+2,因此我们担心这样的过程会导致不能找到正确的Majority Element,但事实是我们会得到正确的结果。假设最坏的情况:剩下的k+2个数字是互不相同的,如下:

[1,1,1,1,2,3,4,5]

这个数组中有8个元素,Majority Element是1,剩下的元素互不相同。在遍历前四个元素的时候count1加到4,当到达第五个元素时候,该元素不等于EM1,此时count2 = 0,因此我们会把当前元素赋值给EM2,此时count1并不发生变化。遍历到第六个元素时,当前元素与EM1和EM2都不相同。此时count1和count2才会减1。继续这个过程直到遍历完成所有的元素,我们可以看到在这个过程中,剩下的元素有一半会被赋值给EM2,而另一半元素才会使得count1--。因此count1最多减(2k+1)/2 = k次,所以如果只有一个Majority Element的话,它肯定会出现在结果中。上面只是举了最坏的情况,对于任意一种排列方式,和任意的情况这个结论都是成立的。


【java代码】

 public class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> list = new ArrayList<Integer>();
if(nums == null || nums.length == 0) return list; int num1 = nums[0], num2 = 0;
int count1 = 0, count2 = 0; for(int i = 0; i < nums.length; i++){
if(num1 == nums[i]) count1++;
else if(num2 == nums[i]) count2++;
else if(count1 == 0){
num1 = nums[i];
count1++;
}
else if(count2 == 0){
num2 = nums[i];
count2++;
}
else{
count1--;
count2--;
}
} count1 = 0; count2 = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] == num1) count1++;
else if(nums[i] == num2) count2++;
}
if(count1 > nums.length/3) list.add(num1);
if(count2 > nums.length/3) list.add(num2); return list;
}
}

LeetCode OJ 229. Majority Element II的更多相关文章

  1. 【LeetCode】229. Majority Element II

    Majority Element II Given an integer array of size n, find all elements that appear more than ⌊ n/3 ...

  2. 【刷题-LeetCode】229. Majority Element II

    Majority Element II Given an integer array of size n, find all elements that appear more than ⌊ n/3 ...

  3. 【LeetCode】229. Majority Element II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 hashmap统计次数 摩尔投票法 Moore Vo ...

  4. LeetCode OJ:Majority Element II(主元素II)

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

  5. leetcode 169. Majority Element 、229. Majority Element II

    169. Majority Element 求超过数组个数一半的数 可以使用hash解决,时间复杂度为O(n),但空间复杂度也为O(n) class Solution { public: int ma ...

  6. [LeetCode] 229. Majority Element II 多数元素 II

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

  7. Leetcode # 169, 229 Majority Element I and II

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

  8. 229. Majority Element II -- 找出数组中出现次数超过 ⌊ n/3 ⌋ 次的数

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

  9. 229. Majority Element II My Submissions Question

    Total Accepted: 23103 Total Submissions: 91679 Difficulty: Medium Given an integer array of size n, ...

随机推荐

  1. Openjudge-NOI题库-旅行-数论

    题目描述 Description 转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活.在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于 ...

  2. Jenkins slave image

    Add a new shell script configure_slave.sh as following: #!/bin/bash dnf -openjdk git wget openssh-se ...

  3. 转:AFNetworking 与 UIKit+AFNetworking 详解

    资料来源 : http://github.ibireme.com/github/list/ios GitHub : 链接地址 简介 : A delightful iOS and OS X networ ...

  4. 内存/硬盘/io关系

    CPU:工人,干活的,判断以及逻辑处理 硬盘:仓库,原料,数据存储 内存:车间,工人干活的地方,车间中加工原料,当车间中没有原料了,在从仓库中取原料,对原料进行加工  内存本身有一定的存储空间,对内存 ...

  5. 拒绝深坑!记录找了多半天时间的C++编译失败的错误

    采用新的源码,和原来的服务改动也不是很大,但是拒绝深坑啊,找了半天以为是源码的问题,结果倒好原来是环境的问题,还是要感谢一个神一样的人物的帮助 编译的时候一直出现undefined reference ...

  6. maven中在本地maven仓库添加jar包

    Maven 手动添加 JAR 包到本地仓库 Maven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,4个人共用,有时候用  ...

  7. 关于LeetCode的Largest Rectangle in Histogram的低级解法

    在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...

  8. UserDefault数据读取

    //GameScene.h #include "cocos2d.h" USING_NS_CC; class GameScene : public cocos2d::Layer{pu ...

  9. C++友元

    通过friend关键字,我们可以将不属于当前类的一个函数在当前类中加以声明,该函数便可以成为当前类的友元函数. 例1: #include<iostream>using namespace ...

  10. Spark Streaming的wordcount案例

    之前测试的一些spark案例都是采用离线处理,spark streaming的流处理一样可以运行经典的wordcount. 基本环境: spark-2.0.0 scala-2.11.0 IDEA-15 ...