题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
注意:本题与主站 169 题相同:https://leetcode.cn/problems/majority-element/
解法
方法一:摩尔投票法
摩尔投票法的基本步骤如下:
初始化元素 \(m\) ,并给计数器 \(cnt\) 赋初值 \(cnt=0\) 。对于输入列表中每一个元素 \(x\) :
若 \(cnt=0\) ,那么 \(m=x\) and \(cnt=1\) ;
否则若 \(m=x\) ,那么 \(cnt=cnt+1\) ;
否则 \(cnt=cnt-1\) 。
一般而言,摩尔投票法需要对输入的列表进行两次遍历 。在第一次遍历中,我们生成候选值 \(m\) ,如果存在多数,那么该候选值就是多数值。在第二次遍历中,只需要简单地计算候选值的频率,以确认是否是多数值。由于本题已经明确说明存在多数值,所以第一次遍历结束后,直接返回 m 即可,无需二次遍历确认是否是多数值。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(1)\) 。其中 \(n\) 为数组长度。
Python3 Java C++ Go Rust JavaScript C# Swift
class Solution :
def majorityElement ( self , nums : List [ int ]) -> int :
cnt = m = 0
for v in nums :
if cnt == 0 :
m , cnt = v , 1
else :
cnt += 1 if m == v else - 1
return m
1
2
3
4
5
6
7
8
9
10
11
12
13
14 class Solution {
public int majorityElement ( int [] nums ) {
int cnt = 0 , m = 0 ;
for ( int v : nums ) {
if ( cnt == 0 ) {
m = v ;
cnt = 1 ;
} else {
cnt += ( m == v ? 1 : - 1 );
}
}
return m ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14 class Solution {
public :
int majorityElement ( vector < int >& nums ) {
int cnt = 0 , m = 0 ;
for ( int & v : nums ) {
if ( cnt == 0 ) {
m = v ;
cnt = 1 ;
} else
cnt += ( m == v ? 1 : -1 );
}
return m ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 func majorityElement ( nums [] int ) int {
cnt , m := 0 , 0
for _ , v := range nums {
if cnt == 0 {
m , cnt = v , 1
} else {
if m == v {
cnt ++
} else {
cnt --
}
}
}
return m
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 impl Solution {
pub fn majority_element ( nums : Vec < i32 > ) -> i32 {
let mut m = 0 ;
let mut cnt = 0 ;
for & v in nums . iter () {
if cnt == 0 {
m = v ;
cnt = 1 ;
} else {
cnt += if m == v { 1 } else { - 1 };
}
}
m
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 /**
* @param {number[]} nums
* @return {number}
*/
var majorityElement = function ( nums ) {
let cnt = 0 ,
m = 0 ;
for ( const v of nums ) {
if ( cnt == 0 ) {
m = v ;
cnt = 1 ;
} else {
cnt += m == v ? 1 : - 1 ;
}
}
return m ;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 public class Solution {
public int MajorityElement ( int [] nums ) {
int cnt = 0 , m = 0 ;
foreach ( int v in nums )
{
if ( cnt == 0 )
{
m = v ;
cnt = 1 ;
}
else
{
cnt += m == v ? 1 : - 1 ;
}
}
return m ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 class Solution {
func majorityElement ( _ nums : [ Int ]) -> Int {
var cnt = 0
var m = 0
for v in nums {
if cnt == 0 {
m = v
cnt = 1
} else {
cnt += ( m == v ? 1 : - 1 )
}
}
return m
}
}