LeetCode:Majority Element I II 投票算法

来源:互联网 发布:软件配置管理 培训 编辑:程序博客网 时间:2024/06/05 22:33

投票算法

因为这两道题涉及到投票算法的思想,所以先从什么是投票算法入手。

Boyer-Moore majority vote algorithm(摩尔投票算法)是一种在线性时间O(n)和空间复杂度的情况下,在一个元素序列中查找包含最多的元素。

在它最简单的形式就是,查找最多的元素,也就是在输入中重复出现超过一半以上(n/2)的元素。如果序列中没有最多的元素,算法不能检测到正确结果,将输出其中的一个元素之一。

当元素重复的次数比较小的时候,对于流算法不能在小于线性空间的情况下查找频率最高的元素。

算法描述

算法在局部变量中定义一个序列元素(m)和一个计数器(i),初始化的情况下计数器为0. 算法依次扫描序列中的元素,当处理元素x的时候,如果计数器为0,那么将x赋值给m,然后将计数器(i)设置为1,如果计数器不为0,那么将序列元素m和x比较,如果相等,那么计数器加1,如果不等,那么计数器减1。处理之后,最后存储的序列元素(m),就是这个序列中最多的元素。

如果不确定是否存储的元素m是最多的元素,还可以进行第二遍扫描判断是否为最多的元素。

输出元素出现次数大于n/2的数代码:

class Solution {public:    // moore majority vote algorithm    int majorityElement(vector<int>& nums) {        int cand;        int count = 0;        for (int i = 0; i < nums.size(); i++) {            if (count == 0) {                cand= nums[i];                count++;            } else if (nums[i] == cand) {                count++;            } else                count--;        }        return cand;    }};

还有一种通用的情况:

输出元素出现次数大于n/k的数

思路:需要维持一个长度为k-1的候选者数组及统计数组。如果候选者数组没有满,将其加入,相应的统计数计为1,如果在候选数组中出现过,将其计数加1,如果没有出现,将所有的计数减1


代码:

class Solution   {  private:      vector<int> majorityElement(vector<int>& nums, int k)      {          int cnt = k - 1;            vector<int> candidates(cnt, 0);          vector<int> count(cnt, 0);            for (int num : nums)          {              bool found = false;              for (int i = 0; i < cnt; i++)              {                  if (!count[i] || num == candidates[i])                  {                      count[i]++;                      candidates[i] = num;                      found = true;                      break;                  }              }                if (!found)              {                  for (int i = 0; i < cnt; i++)                  {                      count[i]--;                  }              }          }            for (int i = 0; i < cnt; i++)          {              count[i] = 0;          }            for (int num : nums)          {              for (int i = 0; i < cnt; i++)              {                  if (num == candidates[i])                  {                      count[i]++;                      break;                  }              }          }            vector<int> ans;          for (int i = 0; i < cnt; i++)          {              if (count[i] > nums.size() / k) ans.push_back(candidates[i]);          }            return ans;      }  };  

Majority Element I

这一题就是上面投票算法:输出元素出现次数大于n/2的数
 时间O(n) 空间 O(1)
C++ AC代码:
class Solution {public:    int majorityElement(vector<int>& nums) {        int len = nums.size();        int variable;        int times=0;        for(int i=0;i<len;i++){             if(times==0){                variable=nums[i];            }            if(variable==nums[i])                times++;            else                times--;                    }        return variable;    }};

Majority Element II

这一题就是上面投票算法:使用通用输出元素出现次数大于n/k的数
时间O(n) 空间 O(1)
C++ AC代码:
 
class Solution {public:    vector<int> majorityElement(vector<int>& nums) {        int len = nums.size();        int cnt = 2;        vector<int> cand(cnt,-1);        vector<int> count(cnt,0);        vector<int> res;        for(int i=0;i<len;i++){            bool found = false;            for(int j=0;j<cnt;j++){                if(cand[j]==nums[i]){                    count[j]++;                    cout<<nums[i]<<" "<<cand[j]<<" "<<count[j]<<endl;                    found = true;                    break;                }            }            for(int j=0;j<cnt;j++){                if(!count[j]&&!found){                    count[j]++;                    cand[j] = nums[i];                    cout<<nums[i]<<" "<<cand[j]<<" "<<count[j]<<endl;                    found = true;                    break;                }            }            if(!found){                cout<<nums[i]<<endl;                for(int j=0;j<cnt;j++)                    count[j]--;            }        }        for(int i=0;i<cnt;i++)            count[i]=0;        for(int i=0;i<len;i++){            for(int j=0;j<cnt;j++){                if(cand[j]==nums[i]){                    count[j]++;                    break;            }         }        }        for(int i=0;i<cnt;i++){            cout<<cand[i]<<endl;            if(count[i]>len/(cnt+1))                res.push_back(cand[i]);        }        return res;    }};

原创粉丝点击