算法训练 || 169、多数元素

169、多数元素

算法训练 || 169、多数元素_第1张图片

方法一:排序+遍历

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];
    }
}

算法训练 || 169、多数元素_第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;
    }
}

算法训练 || 169、多数元素_第3张图片

方法四:哈希表

使用哈希表的时候有三个概念要明确:

  1. 为什么要映射?
  2. 有什么可以映射?
  3. 怎么映射?

下面逐渐来回答这三个问题:

一、为什么要映射

使用哈希表的主要作用是用来快速统计链表/数组/队列中每个元素出现的次数

二、有什么可以映射

这道题中,数组的元素值可以代表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。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。

有了上面的思路基础,对应的代码如下:

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();
    }
}

算法训练 || 169、多数元素_第4张图片

你可能感兴趣的:(java,算法训练,算法,leetcode)