class Solution {
public int majorityElement(int[] nums) {
if(nums.length == 1) return nums[0];
//将数组排序是为了统计
Arrays.sort(nums);
//统计变量
int count = 1, maxcount = 0;
int index = 0, num = nums[0];
while(index < nums.length - 1){
if(nums[index+1] == nums[index]){
count++;
}else{
maxcount = Math.max(count, maxcount);
count = 1;
}
if(count >= maxcount){
num = nums[index];
}
index++;
}
return num;
}
}
复杂度分析:O(nlogn)
空间复杂度:O(1)
根据题目的意思,将数组排完序之后可以得出结论,排完序后数组[n/2]位置的元素就是原数组的多数元素。
class Solution {
public int majorityElement(int[] nums) {
if(nums.length == 1) return nums[0];
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)
摩尔投票法专门用来解决求多数元素,即出现次数大于n/2的情况的元素。在摩尔投票法中,我们假设最后的结果为candidate,选中票数为vote,当前位置的数组元素为num[i],那么投票算法可以这样表示:
初始化时,设置candidate = num[0],然后开始遍历数组,如果candidate = num[i],那么vote++,如果canditate != num[i],vote–,如果vote == 0了,则candidate = num[i];
摩尔投票法的好处就是可以将时间复杂度压缩至O(n),空间复杂度可以压缩至O(1);
从上面的思路可以写出下面的代码:
class Solution {
public int majorityElement(int[] nums) {
int candidate = nums[0];
int vote = 0;
for(int i = 0; i < nums.length; i++){
if(vote == 0){
candidate = nums[i];
}
if(candidate != nums[i]){
vote--;
}else{
vote++;
}
}
return candidate;
}
}
使用哈希表的时候有三个概念要明确:
下面逐渐来回答这三个问题:
一、为什么要映射
使用哈希表的主要作用是用来快速统计链表/数组/队列中每个元素出现的次数
二、有什么可以映射
这道题中,数组的元素值可以代表key,出现的次数可以代表value,这样就可以建立映射关系
三、怎么映射
对于现在的这道题,我们可以用key表示数组中一个元素,用value表示该元素出现的次数,遍历一遍nums数组,将每一个元素加入哈希映射中,在这之后,遍历所有的键值对,返回最大的value对应的key。
API说明
Map是java中的接口,Map.Entry是Map的一个内部接口。
Map提供了一些常用方法,如keySet()、entrySet()等方法。
keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。
Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry
有了上面的思路基础,对应的代码如下:
class Solution {
public int majorityElement(int[] nums) {
int max = 0;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
//遍历数组,建立映射关系
for(int i = 0; i < nums.length; i++){
if(map.get(nums[i]) == null){
map.put(nums[i],1);
}else{
map.put(nums[i],map.get(nums[i])+1);
}
}
//majorityEntry用来存放value最大的key:value对
Map.Entry<Integer,Integer> majorityEntry = null;
//遍历所有的键值对,并返回value最大的key值
//一个entry就是一个key:value对
for(Map.Entry<Integer,Integer> entry : map.entrySet()){
if(majorityEntry == null || entry.getValue() > majorityEntry.getValue()){
majorityEntry = entry;
}
}
return majorityEntry.getKey();
}
}