博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
剑指Offer FindNumberMoreThanHalf 找出数组中出现次数超过一半的数字
阅读量:4207 次
发布时间:2019-05-26

本文共 3958 字,大约阅读时间需要 13 分钟。

题目描述:

数组中有一个数字出现次数【超过 不会等于】数组长度的一半,请找出这个数字

思路:

  1. 先对数组进行排序,出现次数超过一半的数组元素一定是该数组的中位数
    这里使用效率比较好的双指针快排
/**     * 基于快排算法     */    public static int findNumberBySort(int[] array) {        if (array == null || array.length == 0) {            return -1;        }        //获取第一轮排序后 排序好元素的最终下标        int resultIndex = partition(array, 0, array.length - 1);        //中位数下标        int middleIndex = array.length / 2;        while (resultIndex != middleIndex) {
//一直循环到找到中位数 if (resultIndex < middleIndex) {
//比中位数小 resultIndex = partition(array, resultIndex + 1, array.length - 1); } else {
//比中位数大 resultIndex = partition(array, 0, resultIndex - 1); } } //检查中位数元素出现次数是否满足数组长度的一半 if (checkNumCount(array, array[resultIndex])) { return array[resultIndex]; } else { return -1; } } /** * 检查元素是否在数组中出现次数超过一半 * * @param array 数组 * @param result 目标元素 * @return true/false */ private static boolean checkNumCount(int[] array, int result) { int count = 0; for (int i = 0; i < array.length; i++) { if (array[i] == result) { count++; } } return count >= array.length / 2; } /** * 双指针快排 */ private static int partition(int[] array, int start, int end) { if (start >= end) { return -1; } int base = array[start]; int leftIndex = start; int rightIndex = end; while (leftIndex != rightIndex) { while (leftIndex < rightIndex && array[rightIndex] >= base) { rightIndex--; } while (leftIndex < rightIndex && array[leftIndex] <= base) { leftIndex++; } if (leftIndex < rightIndex) { int temp = array[leftIndex]; array[leftIndex] = array[rightIndex]; array[rightIndex] = temp; } } array[start] = array[leftIndex]; array[leftIndex] = base; return leftIndex; }

2.不使用排序的话 还可以根据由于该元素在数组中出现的次数大于一半,因此我们可以知道该元素出现的次数只和会大于其余元素出现次数的总和。

因此我们可以用一个变量count来计数,一个变量result用来标识最小元素的值。首先result为第一个元素的值,count初始值为1,遍历数组,如果count为0的话,证明之前的元素中出现最多的元素出现的次数和其余元素出现次数和抵消,从当前元素开始重新计算,即result设置为当前元素,count重新设置为1,如果count不为0的时候再进行判断,如果当前元素不等于result,那么count自减,否则count自增。

注意数组中有可能出现没有元素出现的次数超过数组的一半,因此最后需要进行判断

public static int findNumberByCount(int[] array) {        if (array == null || array.length == 0) {            return -1;        }        int result = array[0];        int count = 1;        for (int i = 1; i < array.length; i++) {            if (count == 0) {
//如果count为0 则把result设置为当前元素 count设置为1 result = array[i]; count = 1; } else if (array[i] == result) {
//如果当前元素和result相同 count+1 count++; } else { count--; } } if (checkNumCount(array,result)){ return result; }else{ return -1; } }

测试:

@RunWith(Parameterized.class)public class FindNumberMoreThanHalfTest {
@Parameterized.Parameters public static List
data(){ List
data = new ArrayList<>(); data.add(new Object[]{
new int[]{
1,2,3,2,2,2,5,4,2}, 2}); data.add(new Object[]{
new int[]{
1,2,3,6,8,5,5,4,2}, -1}); data.add(new Object[]{
null,-1}); return data; } private final int[] array; private final int max; public FindNumberMoreThanHalfTest(int[] array, int max) { this.array = array; this.max = max; } @Test public void testFindBySort() throws Exception { int result = FindNumberMoreThanHalf.findNumberBySort(array); assertEquals(max,result); } @Test public void testFindByCount() throws Exception { int result = FindNumberMoreThanHalf.findNumberByCount(array); assertEquals(max,result); }}

转载地址:http://fhqli.baihongyu.com/

你可能感兴趣的文章
5.PyTorch实现逻辑回归(二分类)
查看>>
6.PyTorch实现逻辑回归(多分类)
查看>>
8.Pytorch实现5层全连接结构的MNIST(手写数字识别)
查看>>
9.PyTorch实现MNIST(手写数字识别)(2卷积1全连接)
查看>>
hdu 3460 Ancient Printer(trie tree)
查看>>
中间数
查看>>
KMP求前缀函数(next数组)
查看>>
KMP
查看>>
poj 3863Business Center
查看>>
Android编译系统简要介绍和学习计划
查看>>
Android编译系统环境初始化过程分析
查看>>
user2eng 笔记
查看>>
DRM in Android
查看>>
ARC MRC 变换
查看>>
Swift cell的自适应高度
查看>>
【linux】.fuse_hiddenXXXX 文件是如何生成的?
查看>>
【LKM】整合多个LKM为1个
查看>>
【Kernel】内核热补丁技术揭秘
查看>>
【Error】/usr/bin/env: ‘python’: No such file or directory
查看>>
手工挂载VMware共享目录
查看>>