关闭

Majority Element解决:Moore's Voting Algorithm

标签: Moores Voting AlgoriMajority Element
359人阅读 评论(0) 收藏 举报
分类:
【前言】最近再刷leetcode的时候,遇到了一道关于主要元素的题目,题目如下:
Given an array of size , 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.

然后发现了一个类似投票的算法:A Linear Time Majority Vote Algorithm点击打开链接

算法主要解决在元素序列中找到出现次数较多的元素。

算法思想:

每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。
不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。

【解决思路】定义一个记录次数的数组count,count如果为0,则把改变当前候选者元素candidate,并把count设为1;否则根据当前元素e与候选者元素candidate比较来决定增加或减去count,最后的候选者元素即为所求;

候选者元素candidate即出现的count(次数)最多的元素。

When we move the pointer forward over an element e:

  • If the counter is 0, we set the current candidate to e and we set the counter to 1.
  • If the counter is not 0, we increment or decrement the counter according to whethere is the current candidate.
When we are done, the current candidate is the majority element, if there isa majority.

该题目中需要定义一个count,对应candidate出现的次数,代码如下:

         public int majorityElement3(int[] nums) {  
               if(nums.length==0)  
                   return 0;  
               int count=0;  
               int candidate=0;  
               for(int i : nums){  
                   if(candidate ==i)  
                       count++;  
                   else if(count==0){  
                       candidate =i;  
                       count=1;  
                   }  
                   else  
                       count--;  
               }  
               count=0;  
               for(int i : nums){  
                   if(i==candidate)  
                       count++;  
               }  
               return count>nums.length/2?candidate :0;     
           }  

【问题2】

Given an integer array of size n, 
find all elements that appear more than n/3 times. The algorithm should run in linear time and in O(1) space.


该题目中需要定义一个count数组,分别对应两个candidate出现的次数(元素出现次数大于n/3,至多两个candidate),代码如下:


         /**
      * Given an integer array of size n, 
      * find all elements that appear more than n/3 times. The algorithm should run in linear time and in O(1) space.
      * @param nums
      * @return
      */
     public List<Integer> majorityElement2(int[] nums) {
           /*
           A Linear Time Majority Vote Algorithm
           每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。
           不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。
           top 2  Majority Element (more than n/3 times.)
            */
            List<Integer> list=new ArrayList<Integer>();
            if(nums==null)
                return list;
            int[] count=new int[2];
            int[] candidate=new int[2];
            candidate[0]=0;
            candidate[1]=1;
            for(int i : nums){
                if(candidate[0]==i){
                    count[0]++;
                }
                else if(candidate[1]==i){
                    count[1]++;
                }
                else if(count[0]==0){
                    candidate[0]=i;
                    count[0]=1;
                }
                else if(count[1]==0){
                    candidate[1]=i;
                    count[1]=1;
                }
                else{
                    count[0]--;
                    count[1]--;
                }
            }
            for(int j=0;j<2;j++){
                count[j]=0;
            }
            for(int k : nums){//验证count是否满足n/3
                if(k==candidate[0])
                     count[0]++;
                else if(k==candidate[1])
                    count[1]++;
            }
            for(int l=0;l<2;l++){
                if(count[l]>nums.length/3&&!list.contains(candidate[l]))
                     list.add(candidate[l]);
            }
            return list;
        }

总结:上述算法的时间复杂度为O(n),而由于并不需要真的删除数组元素,我们也并不需要额外的空间来保存原始数组,空间复杂度为O(1)。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15280次
    • 积分:326
    • 等级:
    • 排名:千里之外
    • 原创:18篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    最新评论