zoukankan      html  css  js  c++  java
  • 寻找多数元素

    定义:序列中的多数元素是指在一个元素个数为n的序列中,多数元素出现次数大于[n/2].

    寻找元素方法很多:

    1.可以暴力搜索,将每个元素都与其他元素作比较,然后统计该元素出现的次数,时间复杂度为O(n2);

    2.可以先排序,然后再统计每个元素出现的次数,时间复杂度为O(nlogn);

    3.可以寻找中间值元素,因为多数元素在序列中必为中间值元素,时间复杂度是O(n);(寻找中间值元素可以运用寻找第k小元素算法:http://www.cnblogs.com/7hat/p/3411756.html

    这里要介绍第4种方法,时间复杂度也是O(n),但是隐藏常数会比寻找中间值的方法要小。

    算法基于以下观察:在原序列中去除两个不同的元素后,那么在原序列中的多数元素在新序列中还是多数元素。

    算法基本思路:

    (1)在寻找多数元素的过程中,将计数器置1,遇到相同元素则计数器加1,遇到不同元素则计数器减1,一直到计数器等于0或遍历完整个序列。由此可见,计数器的值表示当前元素抵消掉不同元素后的出现次数;

    (2)当计数器在遍历完整个序列前就已经是0,则忽略掉已经遍历过的元素(可以看作两两抵消不影响序列中的多数元素),跳到下一个元素然后计数器重新置1,重复上述步骤,一直到遍历完整个元素;

    (3)当遍历完整个序列后,算法会返回一个值,此时我们还需要检测一次这个值是否真的是多数元素,即遍历统计一次。这一步不可或缺。因为上述两个步骤到了遍历完序列后必将返回一个值,无论序列有无多数元素。此值存在三种情况,第一,它真的是多数元素;第二,它只是序列后面的某个元素刚好抵消完序列;第三,两者皆是。我们必须检测一次。

    算法的实现:

    基本上和上面思路一样,这里我给出递归代码和迭代代码。需要注意的是,因为有可能不存在多数元素,所以需要一个boolean变量来表示是否找到。

    public class majority{
    
        private static boolean flag;
    
        private static int candidate(int k, int[] A){
            //find the candidate may be a majority
            int i = k;
            int x = A[k];
            int count = 1;    //indicates the current element occurrences, after offset different elements
            while(i < A.length-1 && count > 0){
                //remove two different elements, the majority element will not change
                i ++;
                if(A[i] == x){
                    count ++;
                }
                else{
                    count --;
                }
            }
            //there are three cases of x: x is the majority element or x is the last element or both
            if(i == A.length-1)return x;
            return candidate(i+1, A);
        }
        public static int findMajority(int[] A){
            //find the majority
            int x = candidate(0, A);
            int count = 0;
            for(int i = 0; i < A.length; i ++){
                //Test whether x is really the majority of elements in the array
                if(A[i] == x){
                    count ++;
                }
            }
            if(count > A.length/2){
                flag = true;
                return x;
            }
            else{
                flag = false;
                return 0;
            }
        }
        public static int findMajority1(int[] A){
            //Iteration
            int x = 0;
            for(int i = 0; i < A.length; i ++){
                int count = 1;
                x = A[i];
                while(i < A.length-1 && count > 0){
                    i ++;
                    if(A[i] == x){
                        count ++;
                    }
                    else{
                        count --;
                    }
                }
            }
            int count = 0;
            for(int i = 0; i < A.length; i ++){
                if(A[i] == x)count ++;
            }
            if(count > A.length/2){
                flag = true;
                return x;
            }
            else{
                flag = false;
                return 0;
            }
        }
        public static void main(String[] args){
            int[] A = {2, 3, 2, 4, 2};
            int x1 = findMajority(A);
            if(flag){
                System.out.println("Found it: " + x1);
            }
            else{
                System.out.println("Not found!");
            }
            int x2 = findMajority1(A);
            if(flag){
                System.out.println("Found it: " + x2);
            }
            else{
                System.out.println("Not found!");
            }
    
        }
    }
    Java
  • 相关阅读:
    峰哥说技术:14-Spring Boot异常处理方案源码解析与实践
    峰哥说技术:13-Spring Boot ControllerAdvice处理全局异常
    峰哥说技术:12-Spring Boot文件上传
    峰哥说技术:11-Spring Boot返回JSON
    Vant+小程序+购物车实例
    Element-ui框架Tree树形控件切换高亮显示选中效果
    Element-ui框架checkbox复选框回显
    Vue+Element-ui+DateTimePicker 日期时间选择器传值给后台
    Vue+Element+Select获取选中的对象
    Vue+Element+computed实现购物车
  • 原文地址:https://www.cnblogs.com/7hat/p/3416359.html
Copyright © 2011-2022 走看看