LeetCode题集 —— 多数元素——拓展摩尔投票法

LeetCode题集 —— 多数元素——拓展摩尔投票法_第1张图片

目录

题目一:多数元素

         思路一:暴力求解

         思路二:中位数

        思路三:摩尔投票法

题目二:主要元素

题目三:多数元素 【2】


题目一:多数元素

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例: 

LeetCode题集 —— 多数元素——拓展摩尔投票法_第2张图片

 思路一:暴力求解

class Solution {
    public int majorityElement(int[] nums) {
        int count=0;
        int data=0;//记录当前的数
        int x=0;//记录下标
        for(int j=0;jnums.length/2) {
                x=j;
                break;
            }
        }
        return nums[x];
    }
}

上述思路没有问题,但是题目中有要求时间复杂度和空间复杂度的要求,当前的代码,时间复杂度为 O(N^2)

所以上述解法不满足

 思路二:中位数

         思考,数组中必然有一个数的出现次数是大于n/2的,注意,不是大于等于,而是大于,意味着,我们要寻找的数据是超过总数据长度的一半的,也就是说我们给这组数据排序,最中间的数必然是我们要寻找的数据。        

正常情况:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第3张图片

一共18个数,中位数是第九个数

稍微特殊一点的情况: 

 LeetCode题集 —— 多数元素——拓展摩尔投票法_第4张图片

 一共20个数,中位数是第十个数 

代码如下:

import java.util.Arrays;
class Solution {
    public int majorityElement(int[] nums) {
       Arrays.sort(nums);
       return nums[nums.length/2];
    }
}

提交通过:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第5张图片

思路三:摩尔投票法

摩尔投票法:

算法包括两个阶段

1. 对抗阶段:分属两个候选人的票数两两对抗抵消
2. 计数极端:计算对抗结果中最后留下的候选人票数是否有效

打个比方理解一下:

  • 我们把这个数组想象成一排士兵,他们来自不同的队伍,而且不同队伍都是敌对关系,也就是说两两相遇就会开打。
  • 假设从左往右进行车轮战,每个士兵的战斗力相同,即敌对士兵两两开打必会两败俱死!假设【势力】为某国士兵的个数,即同国士兵相遇会【势力】+ 1
  • 当车轮战结束后,最后是没有人活着,或者活下来的都是同一国家的
  • 那么活下来的势力一定就是参战中势力最雄厚的嘛(指人最多)?不是的,假设总共有2n+1个士兵参战,其中n个属于一方,另n个属于另一方,最后一方势力只有一个人,也许前两方杀红了眼两败俱伤了,最后被剩下的一个人捡漏了也是可能的。
  • 怎么判断这个人是捡漏的呢?人不够多。假如【势力】超过总人数的一半,那绝对不会出现捡漏的。 

所以呀,本题目中,强调的是,总会有一个数的出现次数是大于n/2,强调强调,是大于n/2

因此,我们就可以使用摩尔投票法解决本题

我们假设第一个元素就是【势力】最强的队伍的候选队伍,用count记录,如果后一个数与当前元素相同,则count加一,不同则减一,当count为0时,将最强队伍的候选队伍改为当前正在遍历的下一个元素,重复上述操作,一一抵消后,如果是【势力】最强的队伍,那count必然是 > 0的

代码如下:

class Solution {
    public int majorityElement(int[] nums) {
        int answer = 0;
        int count = 0;
        answer=nums[0];
        for(int i=0;i

提交通过:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第6张图片

利用摩尔投票法,再练习几个习题吧,趁热打铁

题目二:主要元素

题目要求: 

LeetCode题集 —— 多数元素——拓展摩尔投票法_第7张图片

         需要注意的是,这里所给数据不一定有【势力】最强的队伍,所以我们需要再遍历一次数组,判断answer出现的次数,是不是大于n/2,防止有队伍捡漏。

代码:

class Solution {
    public int majorityElement(int[] nums) {
        int count=0;
        int answer=nums[0];
        for(int i=0;inums.length/2) {
            return answer;
        }
        return -1;
    }
}

运行通过:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第8张图片

题目三:多数元素 【2】

难度稍稍升级

题目:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第9张图片

仔细读题:给定一个大小为 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 

如果说,一个数组中,有某个数据重复出现的次数大于n/3,那思考一下,可能存在这样的数据,也可能不存在,如果存在的话,可能会存在一个这样的数据,最多存在2个,

为什么呢?思考一下,如果存在三个,那每个数据的个数都超过了n/3,这一共加起来,总个数早都超出了数组的长度。

代码:

import java.util.ArrayList;
import java.util.List;

class Solution {
    public List majorityElement(int[] nums) {
        int answer1=nums[0];//假设的候选队伍1
        int answer2=nums[0];//假设的候选队伍2
        int count1=0;
        int count2=0;
        List answer=new ArrayList<>();
        for(int i=0;inums.length/3) {
            answer.add(answer1);
        }
        if(count2>nums.length/3) {
            answer.add(answer2);
        }
        return answer;
    }
}

重点看一下代码中的,if  ,else if ,else 这几行代码,捋捋。用几组数组数据,试一试,就会明白的。加油!!!

提交通过:

LeetCode题集 —— 多数元素——拓展摩尔投票法_第10张图片

 

本期结束啦,下期见!!!

LeetCode题集 —— 多数元素——拓展摩尔投票法_第11张图片

你可能感兴趣的:(LeetCode,Java,leetcode,算法,职场和发展)