LintCode主元素

  主元素1:

       这道题是编程之美上的一道原题,如果题目未对时间复杂度有严格要求的话可以先排序,再取中位数。

       本题中要求算法达到时间复杂度为O(n),空间复杂度为O(1),算法如下:

 public int majorityNumber(ArrayList<Integer> nums) {
        int count = 0;
        int mainElement = -1;
        for(int i = 0; i < nums.size(); i++){
            if(count == 0){
                count = 1;
                mainElement = nums.get(i);
            } else if(mainElement == nums.get(i)){
                count ++;
            } else{
                count --;
            }
        }
        return mainElement;
    }

      基本思想是每次删除使两个不同的数字两两“抵消”,每次剩下的元素中主元素的次数仍然应该超过总个数的一半,不断重复此过程。

      这个过程如果觉得不好理解的话,我在牛客网看到一个简单易懂的解释:第一个数字作为第一个士兵,守阵地;count = 1; 遇到相同元素,count++;遇到不相同元素,即为敌    人,同归于尽,count--; 当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,则可能是主元素。

  主元素2:

  给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。

  这道题并没有好的思路。简单的用哈希表统计每个数字出现的次数,在遍历哈希表找到符合要求的数字。时间复杂度O(n),空间复杂度O(n)。

 public int majorityNumber(ArrayList<Integer> nums) {
        // write your code
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i = 0; i < nums.size(); i++){
            if(!map.containsKey(nums.get(i))){
                map.put(nums.get(i),1);
            } else {
                Integer count = map.get(nums.get(i));
                map.put(nums.get(i), ++count);
            }
        }
        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            if(entry.getValue() > nums.size()/3){
                return entry.getKey();
            }
        }
        return 0;
    }

 

posted @ 2018-03-19 15:45  _fred  阅读(249)  评论(0编辑  收藏  举报