题目
题目链接入口:JZ39 数组中出现次数超过一半的数字
思路
1.核心考点
(1)数组使用,简单算法设计
2.解题思路
这道题的整体思路比较清晰,以下主要介绍3种思路:
(1)思路一 哈希法:使用unordered_map,使用<数字元素,出现次数>的映射关系,遍历题目给出的数组,如果是当前数字是第一次出现就构建pair插入到unordered_map中,如果之前已经插入了这个数字,那么就自增。统计出数组中每个元素出现的次数之后,再遍历一次数组,找出众数。
时间复杂度O(n),空间复杂度O(n)。
(2)思路二 排序法:使用排序sort,排序之后,出现次数最多的数字,一定在数组的中间位置,然后检测中间出现的数字出现次数是否符合要求。
时间复杂度O(nlogn),空间复杂度:O(1)。
(3)思路三 候选法(最优解):
如果数组中存在众数,那么众数一定大于数组的长度的一半。
思想就是:如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数。
代码实现
C++版本
思路一:
#include <unordered_map>
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
unordered_map<int, int> map;
int half=numbers.size()/2;
for(int i=0;i<numbers.size();i++)
{
//如果元素已经插入map中就自增,如果是第一次插入
//就将其出现次数记为1
auto it = map.find(numbers[i]);
if(it==map.end())
{
//第一次出现
map.insert(make_pair(numbers[i], 1));
}
else//之前这个数字已插入map中——自增
{
map[numbers[i]]++;
}
if(map[numbers[i]]>half)
{
return numbers[i];
}
}
//走到这里说明没有找到
return 0;
}
};
思路二:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
sort(numbers.begin(),numbers.end());
int target = numbers[numbers.size()/2];
int count=0;
for(int i=0;i<numbers.size();i++)
{
if(target==numbers[i])
{
count++;
}
}
if(count>numbers.size()/2)
{
return target;
}
return 0;
}
};
思路三:
#include <type_traits>
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
{
return 0;
}
//现以数组的第一个元素为哨兵
int ret = numbers[0];
int count=1;
for(int i=1;i<numbers.size();i++)
{
if(count!=0)
{
//当前数与“哨兵”相同,则count++,否则++
if(numbers[i]==ret)
{
count++;
}
else
{
count--;
}
}
else {
//count==0,说明之前的众数和非众数都抵消了
ret = numbers[i];
count=1;
}
}
//得到这个数之后,还要再遍历一遍数组,判断它的出现次数是否超过数组长度的一半
int k=0;
for(int i=0;i<numbers.size();i++)
{
if(numbers[i]==ret)
{
k++;
}
}
if(k>numbers.size()/2)
{
return ret;
}
return 0;
}
};
java版本
思路一:
import java.util.Map;
import java.util.HashMap;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null){
return 0;
}
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < array.length; i++){
if(map.containsKey(array[i])){
int count = map.get(array[i]);
count++;
map.put(array[i], count);
}else{
map.put(array[i], 1);
}
if(map.get(array[i]) > array.length/2){
return array[i];
}
}
return 0;
}
}
思路二:
import java.util.Arrays;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null){
return 0;
}
Arrays.sort(array);
int target = array[array.length/2];
int count = 0;
for(int i = 0; i < array.length; i++){
if(target == array[i]){
count++;
}
}
if(count > array.length/2){
return target;
}
return 0;
}
}
思路三:
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null){
return 0;
}
int target = array[0];
int times = 1;
for(int i = 1; i < array.length; i++){
if(times == 0){
target = array[i];
times = 1;
}
else if(array[i] == target){
times++;
}
else{
times--;
}
}
times = 0;
for(int i = 0; i < array.length; i++){
if(target == array[i]){
times++;
}
}
return times > array.length/2 ? target : 0;
}
}