Question
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.
Idea
给定一个大小为n的数组,找到其中的多数元素。其中的多数元素是超过n/2次重复的元素。
假定数组不为空,且多数数组始终存在与数组中。
idea1
:由于这里假设数组不为空,且多数元素一定存在,该多数元素大于整个数组的n/2。步骤分为两步:- 对数组进行排序,多数元素一定超过n/2个,所以一定会在该位置上出现;
- 该位置上的元素一定为多数元素,直接返回该元素。
idea2
:Moore voting algorithm.- 算法思想:每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素;
- 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。
idea3
:一个更为直观的想法是,利用HashMap来实现每个元素与其个数一一对应,成为映射对。- 相对idea1和idea2的时间消耗更大。
Code
idea1—Java
public class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
- 算法简单直接,时间复杂度低,Runtime:4ms.
idea2—Java
public class Solution {
public int majorityElement(int[] nums) {
int major = 0;
int count = 0;
for (Integer num:nums){
if(count == 0){
major = num;
}
if(major != num){
count--;
}else{
count++;
}
}
return major;
}
}
- 在遍历过程中,当前元素与candidate相同则投支持票,否则投反对票。
- 当count状态为0时,说明之前的子数组中不存在重复次数超过一半的数,遍历余下的数组成为原问题的子问题。
- 若该数不一定存在,那么需要再一次遍历数组,鉴证找到的元素是否符合条件。
- Moore 主页上有该问题的一个移步演示。
- 时间复杂度:O(n),空间复杂度O(1)
idea3—Java
public class Solution {
public int majorityElement(int[] nums) {
Map<Integer,Integer> myMap = new HashMap<Integer, Integer>();
int major = 0;
for (Integer num:nums){
if (!myMap.containsKey(num)){
myMap.put(num,1);
}else{
myMap.put(num,myMap.get(num)+1);
}
if (myMap.get(num) > nums.length/2){
major = num;
break;
}
}
return major;
}
}
- 算法利用HashMap的containsKey()方法来判断一个元素是否已经添加其中;
- 如果元素不存在与HashMap中,则利用put()方法将对应的元素与其个数1组成键对放入其中;
- 如果元素存在,则对相应的元素对应的个数+1;
- 在整个循环中判断当前元素的个数是否大于n/2;
- 算法的时间复杂度高,Runtime:53ms。