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.

这里题目要求找出出现次数超过n/2的元素。

可以先排序,出现次数超过一半的元素会出现在数组中间。时间O(nlogn)空间O(1)

无论找出出现次数多于多少的元素,都可以使用HashMap来找,在往map中添加的时候就可以判断了。O(n)时间复杂度和空间复杂度

 public int majorityElement(int[] nums) {
if(nums.length==1) return nums[0];
HashMap<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(map.get(nums[i])==null)
map.put(nums[i],1);
else{
int num=map.get(nums[i]);
if(num+1>nums.length/2) return nums[i];
map.put(nums[i],num+1);
}
}
return 0;
}

多数投票算法。。

该算法时间复杂度为O(n),空间复杂度为O(1),只需要对原数组进行两趟扫描,并且简单易实现。第一趟扫描我们得到一个候选节点candidate,第二趟扫描我们判断candidate出现的次数是否大于⌊ n/2 ⌋。这里题目说元素必然存在,所以第二趟就省略了。先看代码.

   public int majorityElement(int[] nums) {
int candidate=0;int count=0;
for(int i=0;i<nums.length;i++){
if(count==0){
count++;
candidate=nums[i];
}else if(candidate==nums[i]) count++;
else count--;
}
return candidate;
}

我们来看看原理。(参考http://blog.csdn.net/kimixuchen/article/details/52787307)

因为存在超过一半次数的元素,上面算法中,该元素会去抵消其他的元素(抵消一个count就变为0)。然后该元素还有剩余,所以最后的candidate就是该元素了。

为了解析算法的原理,我们只要考虑存在多数元素的情况即可,因为第二趟扫描可以检测出不存在多数元素的情况。

举个例子,我们的输入数组为[1,1,0,0,0,1,0],那么0就是多数元素。 
首先,candidate被设置为第一个元素1,count也变成1,由于1不是多数元素,所以当扫描到数组某个位置时,count一定会减为0。在我们的例子中,当扫描到第四个位置时,count变成0.

count 值变化过程: 
[1,2,1,0……

当count变成0时,对于每一个出现的1,我们都用一个0与其进行抵消所以我们消耗掉了与其一样多的0,而0是多数元素,这意味着当扫描到第四个位置时,我们已经最大程度的消耗掉了多数元素。然而,对于数组从第五个位置开始的剩余部分,0依然是其中的多数元素(注意,多数元素出现次数大于⌊ n/2 ⌋,而我们扫描过的部分中多数元素只占一般,那剩余部分中多数元素必然还是那个数字)。如果之前用于抵消的元素中存在非多数元素,那么数组剩余部分包含的多数元素就更多了。

类似的,假设第一个数字就是多数元素,那么当count减为0时,我们消耗掉了与多数元素一样多的非多数元素,那么同样道理,数组剩余部分中的多数元素数值不变。

这两种情况证明了关键的一点:数组中从candidate被赋值到count减到0的那一段可以被去除,余下部分的多数元素依然是原数组的多数元素。我们可以不断重复这个过程,直到扫描到数组尾部,那么count必然会大于0,而且这个count对应的candinate就是原数组的多数元素。

对于其他求不是超过n/2的,而是n/k的,可以使用map。

majority element(数组中找出出现次数最多的元素)的更多相关文章

  1. BAT面试上机题从3亿个ip中找出访问次数最多的IP详解

    我们面临的问题有以下两点:1)数据量太大,无法在短时间内解决:2)内存不够,没办法装下那么多的数据.而对应的办法其实也就是分成1)针对时间,合适的算法+合适的数据结构来提高处理效率:2)针对空间,就是 ...

  2. 从一亿个ip找出出现次数最多的IP(分治法)

    /* 1,hash散列 2,找到每个块出现次数最多的(默认出现均匀)—–>可以用字典树 3,在每个块出现最多的数据中挑选出最大的为结果 */ 问题一: 怎么在海量数据中找出重复次数最多的一个 算 ...

  3. C语言:对传入sp的字符进行统计,三组两个相连字母“ea”"ou""iu"出现的次数,并将统计结果存入ct所指的数组中。-在数组中找出最小值,并与第一个元素交换位置。

    //对传入sp的字符进行统计,三组两个相连字母“ea”"ou""iu"出现的次数,并将统计结果存入ct所指的数组中. #include <stdio.h& ...

  4. 用C#写一个函数,在一个数组中找出随意几个值相加等于一个值 与迭代器对比

    算法!用C#写一个函数,在一个数组中找出随意几个值相加等于一个值比如,数组{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}  要找出那些数相加等 ...

  5. Leetcode33--->Search in Rotated Sorted Array(在旋转数组中找出给定的target值的位置)

    题目: 给定一个旋转数组,但是你不知道旋转位置,在旋转数组中找出给定target值出现的位置:你可以假设在数组中没有重复值出现 举例: (i.e., 0 1 2 4 5 6 7 might becom ...

  6. 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

    今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...

  7. C语言 选择排序算法原理和实现 从数组中 找出最小的元素然后交换位置

    #include <stdio.h> int main(void) { /* 选择排序算法 原理:从数组中 找出最小的元素然后交换位置: */ int a[10] = {9,5,10,7, ...

  8. 从数组中找出所有组合为s的数

    java版本 package numCombine; /** * 从数组中找出所有组合为s的数 * @author root * */ public class NumComberAll { publ ...

  9. 3sum(从数组中找出三个数的和为0)

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

随机推荐

  1. iOS中 自定义cell分割线/分割线偏移 韩俊强的博客

    在项目开发中我们会常常遇到tableView 的cell分割线显示不全,左边会空出一截像素,更有甚者想改变系统的分割线,并且只要上下分割线的一个等等需求,今天重点解决以上需求,仅供参考: 每日更新关注 ...

  2. OpenCV3.0 3.1版本的改进

     摘要        OpenCV现在更新到了3.1版本,相对OpenCV2有了很大改进,其中对于硬件加速,移动开发(IOS,android)的支持成为亮点.      新版的OpenCV采用了内 ...

  3. 《java入门第一季》之有趣的集合小案例---获取10个【1-20之间】的随机数,要求不能重复。

    import java.util.ArrayList; import java.util.Random; /* * 获取10个[1-20之间]的随机数,要求不能重复.(注意:不是获取10个数,如果单纯 ...

  4. Gitflow工作流程

    在工作场合实施Git的时候,有很多种工作流程可供选择,此时反而会让你手足无措.本文罗列了企业团队最常用的一些Git工作流程,包括Centralized Workflow.Feature Branch ...

  5. 【一天一道LeetCode】#70. Climbing Stairs

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 You are ...

  6. Android Studio安装插件Genymotion

    Android Studio安装插件的方式其实和Eclipse大同小异.废话不多说,直接上图: 区域1:你当前已经安装了的插件 区域2:在线安装 区域3:从硬盘安装,即针对你已经下载好了的插件,可通过 ...

  7. Android进程通信之一:两种序列化方式

    2月下旬辞职了,去海南度假到现在,领略了一把三亚风情也算任性和 然而这样任性带来的后果就是..不行了我必须吐槽一句.. 没毕业的找工作就这么难嘛!投了57家一家面试机会都没有,好歹给个面试机会啊!!本 ...

  8. (四十一)数据持久化的NSCoding实现 -实现普通对象的存取

    NSCoding可以用与存取一般的类对象,需要类成为NSCoding的代理,并且实现编码和解码方法. 假设类Person有name和age两个属性,应该这样设置类: .h文件: #import < ...

  9. Css的学习之旅-css的选择器(2)

    1.最常用的是派生选择器:eg:ul li{ color:red} 2.id选择器:eg:#id{color:red} 3.类选择器:设置标签的class = "",类似id.用点 ...

  10. RAC 10g administration

    10g RAC administration See OCFS Oracle Cluster Filesystem, ASM, TNSnames configuration, Oracle Datab ...