【LeetCode & 剑指offer刷题】数组题7:39 数组中出现次数超过一半的数字

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

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

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
#include <unordered_map> //hash表实现
using namespace std;
//方法一:hash表实现,On,O(n)
class Solution
{
public:
    int MoreThanHalfNum_Solution(vector<int> numbers)
    {
        unordered_map<int,int> counter;
        int k = numbers.size() / 2;
        for(int ai:numbers) //遍历数组 O(n)
        {
            counter[ai]++; //构建计数器
            if(counter[ai] > k) return ai; //节省时间
        }
     //   for(auto& n:counter) //遍历计数器 O(k) ,这里为map中的引用,不是指针,故直接用n.first
       // {
         //   if(n.second > k)
           // {
          //      return n.first;
         //   }
       // }
        return 0; //不存在
      
    }
};
 
/*
方法二:“消解法”:如果一个数出现次数超过数组的一半,则其出现的次数比其他所有数字出现次数的和还要多,可以用两不同数之间进行消解,最后剩下的数即为出现次数最多那个数
缺点:需要判断是否真的次数超过一半,因为上述条件是必要条件但不是充分条件,时间效率没有hash表法好
O(n),O(1)
 
例:
1 2 2 2 3
i=0,t=0,res =1,t=1
i=1,不等,t-1=0
i=2,res =a[2] =2,t=1
i=3,相等,t+1=2
i=4,不等,t-1=1
*/
class Solution
{
public:
    int MoreThanHalfNum_Solution(vector<int> numbers)
    {
        int result = numbers[0];
        int times = 1;
       
        for(int i = 1;i<numbers.size(); i++)
        {
            if(times == 0//候选数,
            {
                result = numbers[i];
                times = 1;
            }
            else if (numbers[i] == result) times++;//相等时次数加一,
            else times--;//不等时减一
        }
       
        times = 0;
        for(int ai:numbers)//判断是否真的次数超过一半
        {
            if(ai == result) times++;
        }
        if(times > numbers.size()/2) return result;
         else  return 0; //不存在
       
       
    }
};
 
 

 

posted @ 2019-01-05 14:05  wikiwen  阅读(408)  评论(0编辑  收藏  举报