剑指offer之找出数组中出现次数超过一半的数字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danielzhou888/article/details/84453771

找出数组中出现次数超过一半的数字

欢迎关注作者简书
csdn传送门

题目

  一个数组中有一个数字的次数超过了数组的一半,求出这个字符。如:int a[] = {2,3,2,2,2,2,2,5,4,1,2,3},求出超过一半的数字是2

分析

解法一

  数组中有一个数字出现的次数超过了数组长度的一半,如果把数组排序,排序之后位于数组中间的数字一定是出现次数超过数组长度一半的数字。排序算法可以使用sort(快排),它的时间复杂度为O(n*logn)。例如:{2,5,7,2,2,8,2,2}排序后为:{2,2,2,2,2,5,7,8} ,中位数2是出现次数超过一半的数字

解法二

  基于Partition函数的O(n)算法
  Partition函数是实现快排的基础。同样是找中位数,受快速排序算法的启发,如果选中的数字的下标是n/2,那么这个数字就是中位数;如果选中的数字的下标大于n/2,则中位数在它的左边,可以接着在它左边部分的数组中查找;如果选中的数字的下标小于n/2,则中位数在它的右边,可以接着在它右边部分的数组中查找。这个过程是一个递归的过程。

源码

本题采用解法一

/**
 * @program:
 * @description: 数组中出现次数超过一半的数字
 * @author: zhouzhixiang
 * @create: 2018-11-24 21:16
 */
public class Test28 {

    /**
     * 找出数组中出现次数超过一半的数字
     * @param numbers
     * @return
     */
    public static Integer moreThanHalfNum(int[] numbers) {
        // 进行快速排序
        quickSort(numbers, 0, numbers.length-1);
        // 排序后的中位数即为目标值
        return numbers[numbers.length/2+1];
    }

    /**
     * 快速排序
     * @param numbers
     * @param left
     * @param right
     */
    private static void quickSort(int[] numbers, int left, int right) {
        if (left < right) {
            int key = numbers[left];
            int low = left;
            int high = right;
            while (low < high) {
                while (low < high && numbers[low] < numbers[key])
                    low++;
                numbers[high] = numbers[low];
                while (low < high && numbers[high] > numbers[key])
                    high--;
                numbers[low] = numbers[high];
            }
            numbers[low] = numbers[key];
            quickSort(numbers, left, low - 1);
            quickSort(numbers, low + 1, right);
        }
    }
}

欢迎加入Java猿社区
欢迎加入Java猿社区.png

猜你喜欢

转载自blog.csdn.net/danielzhou888/article/details/84453771
今日推荐