zoukankan      html  css  js  c++  java
  • 剑指offer-数组中出现次数超过一半的数字

    题目描述

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

    方法1:基于partition函数的算法  

    public class Test {
        
        public static void main(String[] args) {
            int[] a = {1,1,1,3,4};
            System.out.println(moreThanHalfNum(a));
        }
    
        /**
         * 1、对数组进行快速排序,那么位于数组中间的数字一定是那个出现次数超过数组长度一半的数字。
         * @param array
         * @return
         */
        private static int moreThanHalfNum(int[] array) {
            if(array == null || array.length <= 0) 
                return 0;
            int low = 0;
            int high = array.length - 1;
            int mid = array.length >> 1; 
            int index = partition(array, low, high);
            
            while(index != mid) {
                if(index < mid) {
                    index = partition(array, index+1, high);
                } else {
                    index = partition(array, low, index - 1);
                }
            }
            int result = array[mid];
            
            if(!checkMoreThanHalfNum(array, result)) {
                return 0;
            }
            return result;
        }
        
        private static boolean checkMoreThanHalfNum(int[] array, int result) {
            int times = 0;
            for(int i=0; i<array.length; i++) {
                if(array[i] == result) {
                    times ++;
                }
            }
            
            if(times * 2 <= array.length)
                return false;
            return true;
        }
    
        private static int partition(int[] a, int low, int high) {
            int key = a[low];                 // 第一个数作为key,将数组划为两部分
            while(low < high) {                // 左右未相遇
                while(low < high && a[high] >= key)      // 先从数组右边往前寻找第小于key的数(必须从右开始),交换
                    high --;                                
                a[low] = a[high];
                while(low < high && a[low] <= key)     // 再从左往右找大于key的数,交换
                    low ++;
                a[high] = a[low];              
            }
            a[low] = key;   // key放在合适的位置,其左边都小于key,右边都大于key
            return low;
        }
    }

    方法2:

    数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值: 一个是数组中的一个数字, 一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加 l :如果下一个数字和我们之前保存的数字不同,则次数减 1 。如果次数为0,我们需要保存下一个数字,并把次数设为 1 。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为 1 时对应的数字。

    public class Test {
        
        public static void main(String[] args) {
            int[] a = {1,2,3};
            System.out.println(majorityElement(a));
        }
        
        public static int majorityElement(int[] a) {
            if(a == null || a.length <= 0)
                return 0;
            
            int candidate = a[0];  // 用于记录出现次数大于数组长度一半的值
            int nTimes = 1;  // 次数
            for (int i = 1; i < a.length; i++)
            {
                if (nTimes == 0)
                {
                    candidate = a[i];
                    nTimes = 1;
                }
                else
                {
                    if (candidate == a[i])
                        nTimes++;
                    else
                        nTimes--;
                }
            }
            
            if(!checkMoreThanHalfNum(a, candidate))
                return 0;
            return candidate;
        }
        private static boolean checkMoreThanHalfNum(int[] array, int result) {
            int times = 0;
            for(int i=0; i<array.length; i++) {
                if(array[i] == result) {
                    times ++;
                }
            }
            
            if(times * 2 <= array.length)
                return false;
            return true;
        }
    }
  • 相关阅读:
    组合模式扩展,有选择的递归
    SQL分页查询【转】
    facade外观模式
    C#:几种数据库的大数据批量插入 faib
    装饰模式的扩展
    yeild之我理解
    数据库操作 sqlserver查询存储过程+分页
    SQL Server 索引结构及其使用(二)[转]
    SQL索引使用初步,(转)
    解决多集成,多子类,扩展等 装饰模式
  • 原文地址:https://www.cnblogs.com/zywu/p/5782013.html
Copyright © 2011-2022 走看看