作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/majority-element/

Total Accepted: 110538 Total Submissions: 268289 Difficulty: Easy

题目描述

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.

题目大意

找出数组中出现次数超过一半的数字。

解题方法

思路

第一想法,用HashMap。嗯。之前也这么做过,但是一想就不对,肯定效率太差。

然后也没想到太好的方法。但是官方给了几个思路:

  1. 时间复杂度: O(n2) — 蛮力法: 依次检查每一个元素是否为众数

  2. 时间复杂度: O(n), 空间复杂度: O(n) — 哈希表: 维护一个每一个元素出现次数的哈希表, 然后找到出现次数最多的元素

  3. 时间复杂度: O(n log n) — 排序: 在排序后找出连续重复出现次数最多的元素

  4. 平均时间复杂度: O(n), 最坏复杂度: 无穷大 — 随机算法: 随机选取一个元素计算其是否为众数. 如果不是,就重复上一步骤直到找到为止。 由于选出众数的概率 1 / 2, 因此期望的尝试次数 < 2

  5. 时间复杂度: O(n log n) — 分治法: 将数组拆成2半, 然后找出前一半的众数A和后一半的众数B。则全局众数要么是A要么是B。如果 A == B, 则它自然而然就是全局众数。 如果不是, 则A和B都是候选众数, 则至多只需要检查这两个元素的出现次数即可。

  6. 时间复杂度, T(n) = T(n/2) + 2n = O(n log n).

  7. 时间复杂度: O(n) — Moore投票算法: 我们维护一个当前的候选众数和一个初始为0的计数器。遍历数组时,我们看当前的元素x:
    - 如果计数器是0, 我们将候选众数置为 x 并将计数器置为 1 如果计数器非0, 我们根据x与当前的候选众数是否相等对计数器+1或者-1;
    - 一趟之后, 当前的候选众数就是所求众数.

  8. 时间复杂度 = O(n). 时间复杂度: O(n) — 位操作法: 我们需要32次迭代,
    - 每一次计算所有n个数的第i位的1的个数。由于众数一定存在,那么或者1的个数 0的个数多 或者反过来(但绝不会相同)。
    - 众数的第i位一定是计数较多数字。

hashmap统计次数

加入不考虑空间复杂度,直接使用字典统计次数,然后找出出现次数最大的那个数字,就能通过。

python代码如下:

class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
count = collections.Counter(nums)
return count.most_common(1)[0][0]

C++代码如下:

class Solution {
public:
int majorityElement(vector<int>& nums) {
const int N = nums.size();
unordered_map<int, int> count;
for (int n : nums)
++count[n];
for (auto& c : count) {
if (c.second > N / 2) {
return c.first;
}
}
return -1;
}
};

摩尔投票法 Moore Voting

这个投票方法挺好玩。就是多数派问题。

这个思路是这样的:

  1. 对于vi,如果c此时为未知状态,则c=v[i],t=1,递增i。
  2. 如果c==v[i],++t,递增i。
  3. 如果c!=v[i],–t,如果t==0,将c置为未知状态,递增i。
  4. 所有投票处理完毕后,如果c为未知状态,则说明不存在任何候选人的得票数过半,否则重新遍历数组v,统计候选人c的实际得票总数,如果c的得票数确实过半,则c就是最终结果。

这个做法的原理就是既然有出现次数超过一半的数字,那么我们把没出现一半的数字的次数进行抵消,出现一半以上的数字仍然不会被完全消除掉。

比如对于数据[1,2,1,1,3,1,4,4]

i		1	2	3	4	5	6	7	8
v[i] 1 2 1 1 3 1 4 4
c 1 ? 1 1 1 1 1 ?
t 1 0 1 2 1 2 1 0

程序运行的最终结果,c处于未知状态,说明对于投票数组v,不存在任何候选人的得票数过半。

如果v[1…9]={1,2,1,1,3,1,4,4,1},此时c的最后状态为1,重新遍历数组v,查看候选人1的得票数是否确实过半,统计结果1出现了5次,大于9/2,所以候选人1的票数过半。

因为题目中已经保证了存在数据出现过半。所以结尾的c那个元素一定不是不确定状态,直接返回就好。

C++代码如下:

class Solution {
public:
int majorityElement(vector<int>& nums) {
int c = -1;
int t = 0;
for (int n : nums) {
if (t == 0) {
c = n;
t = 1;
} else {
if (n == c) {
++t;
} else {
--t;
}
}
}
return c;
}
};

python版本代码如下:

class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
m = cm = 0
for num in nums:
if m == num:
cm += 1
elif cm == 0:
m = num
cm = 1
else:
cm -= 1
return m

Java代码:

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

位运算统计位数

位操作法: 我们需要32次迭代, 每一次计算所有n个数的第i位的1的个数。

由于众数一定存在,那么或者1的个数0的个数多,或者反过来(但绝不会相同)。

众数的第i位一定是计数较多数字(1或0)。

这个题需要注意的是如何设置一个int的指定位是1:或上一个该指定为是1其余位是0的数字即可。

时间复杂度 = O(n).

一、指定的某一位数置1

宏 #define setbit(x,y)  x|=(1<<y)

二、指定的某一位数置0

宏  #define clrbit(x,y)  x&=~(1<<y)

三、指定的某一位数取反

宏  #define reversebit(x,y)  x^=(1<<y)

三、获取的某一位的值

宏 #define getbit(x,y)   ((x) >> (y)&1)

C++代码如下:

class Solution {
public:
int majorityElement(vector<int>& nums) {
const int N = nums.size();
int res = 0;
for (int i = 0; i < 32; ++i) {
int mask = 1 << i;
int onecount = 0;
for (int n : nums) {
if (n & mask) {
++onecount;
}
}
if (onecount > N / 2)
res |= mask;
}
return res;
}
};

相似题目

229. Majority Element II

参考资料

多数派问题
https://blog.csdn.net/qq_37858386/article/details/78419911

日期

2016/5/1 0:00:49
2018 年 10 月 29 日 —— 美好的一周又开始了
2018 年 11 月 11 日 —— 剁手节快乐

【LeetCode】169. Majority Element 解题报告(Java & Python & C+)的更多相关文章

  1. LeetCode 169 Majority Element 解题报告

    题目要求 Given an array of size n, find the majority element. The majority element is the element that a ...

  2. LeetCode 169. Majority Element解题方法

    题目: Given an array of size n, find the majority element. The majority element is the element that ap ...

  3. 【LeetCode】162. Find Peak Element 解题报告(Python)

    [LeetCode]162. Find Peak Element 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/ ...

  4. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  5. [LeetCode] 169. Majority Element 多数元素

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  6. leetcode 169. Majority Element 、229. Majority Element II

    169. Majority Element 求超过数组个数一半的数 可以使用hash解决,时间复杂度为O(n),但空间复杂度也为O(n) class Solution { public: int ma ...

  7. Leetcode#169. Majority Element(求众数)

    题目描述 给定一个大小为 n 的数组,找到其中的众数.众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] ...

  8. 23. leetcode 169. Majority Element

    169. Majority Element Given an array of size n, find the majority element. The majority element is t ...

  9. Java for LeetCode 169 Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appear ...

随机推荐

  1. CentOS6.9安装python3

    安装依赖包: yum install -y openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel w ...

  2. linux 网络配置管理

    [1]网络配置基础 (1)用户既可以通过命令行的方式,也可以通过友好的图形界面,轻松完成网络配置. (2)实现Linux网络配置的惟一目标就是修改系统中众多的网络配置文件, 如/etc/interfa ...

  3. java输入代码

    import java.util.Scanner; public class Demo59 {    public static void main(String[] args) {        / ...

  4. idea Error : java 不支持发行版本5

    问题描述 在Intellij idea中新建了一个Maven项目,运行时报错如下:Error : java 不支持发行版本5 解决 1.在Intellij中点击"File" --& ...

  5. 浅谈MySQL数据库面试必要掌握知识点

    概述 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 MySQL官方地址 https://www.mysql.com/ MySQL 8系列最新版本为8.0.27,5系列的最 ...

  6. Oracle异常处理——ORA-01502:索引或这类索引的分区处于不可用状态

    Oracle异常处理--ORA-01502:索引或这类索引的分区处于不可用状态参考自:https://www.cnblogs.com/lijiaman/p/9277149.html 1.原因分析经过查 ...

  7. idea maven 项目 遇到 "Module not specified" 解决方法

    1. 原因:我这边出现的原因是 其他同事在提交代码是 将  这个文件夹也提交了,idea 会加载 .idea 里的配置(即 他的配置),而我的 maven 配置不同,导致出错. 2. 解决方法:删除这 ...

  8. SpringBoot+MybatisPlus实现批量添加的两种方式

    第一种: 因为Mysql数据每次发送sql语句的长度不能超过1M,所以,每次发送insert语句以固定长度发送: 将sql语句在provider中,以固定长度装入List集合中,然后返回service ...

  9. View的简单说明

    一)三个结构体:CGPoint.CGSize.CGRect 1. CGPoint struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CG ...

  10. [BUUCTF]REVERSE——[GUET-CTF2019]re

    [GUET-CTF2019]re 附件 步骤: 查壳儿,upx壳,64位程序 upx脱壳儿,然后扔进64位ida,通过检索字符串,找到有关flag的信息定位到关键函数 让我们输入flag,然后满足su ...