Fork me on GitHub

【Offer】[39] 【数组中出现次数超过一半的数字】

题目描述

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

牛客网刷题地址

思路分析

  有两种思路:

  1. 快速排序的思想:数字次数超过一半,可以说明排序之后中间的数字一定是所求的数字,即统计学上的中位数,利用partition函数求得某一下标,如果改下标正好为n/2,则该数字为所求数字,需要检查该数字在数组中出现的次数;如果 < n/2,则中位数位于改下标右边,如果 > n/2 则位于左边;
  2. 统计数字出现的次数,首先先保存一个哨兵数字和一个计数器,遍历数组后面的数字,遇到与该数字相同的则计数器+1,遇到不同的-1,如果计数器减为0时,就重新保存一个数字,重新开始从1开始计数。到最后计数器如果>0,判断该数字出现次数。

测试用例

  1. 功能测试:输入的数组中存在一个出现次数超过数组长度一半的数字:输入的数组中不存在一个出现次数超过数组长度一半的数字。
  2. 特殊输入测试:输入的数组中只有一个数字;输入nullptr 指针。

Java代码

public class Offer39 {
    public static void main(String[] args) {
        test1();
        test2();
        test3();

    }

    public static int MoreThanHalfNum_Solution(int[] array) {
        return Solution1(array);
    }

    /**
     * partition方法
     * 
     * @param array
     * @return
     */
    private static int Solution1(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }
        int middle = array.length >> 1;
        int low = 0;
        int high = array.length - 1;
        int index = partition(array, low, high);
        while (index != middle) {
            if (index < middle) {
                low = index + 1;
                index = partition(array, low, high);
            } else {
                high = index - 1;
                index = partition(array, low, high);
            }
        }

        int result = array[middle];
        int times = 0;
        for (int i = 0; i < array.length; i++) {
            if (result == array[i]) {
                times++;
            }
        }

        if (times * 2 > array.length) {
            return result;
        }
        return 0;
    }

    private static int partition(int[] array, int low, int high) {
        int privot = array[low];
        while(low<high){
            while(low<high && array[high]>=privot) high--;
            array[low] = array[high];
            while(low<high && array[low]<=privot) low++;
            array[high] = array[low];
        }
        array[low] = privot;
        return low;
    }

    private static int Solution2(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }
        int count = 1;
        int flagNum = array[0];
        for (int i = 1; i < array.length; i++) {
            if (count == 0) {
                flagNum = array[i];
                count = 1;
            } else if (array[i] == flagNum) {
                count++;
            } else {
                count--;
            }
        }
        if (count > 0) {
            int times = 0;
            for (int i = 0; i < array.length; i++) {
                if (array[i] == flagNum) {
                    times++;
                }
            }
            if (times * 2 > array.length) {
                return flagNum;
            }
        }
        return 0;
    }

    private static void test1() {
        int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
        int result = MoreThanHalfNum_Solution(array);
        System.out.println(result);
    }

    private static void test2() {
        int[] array = { 1 };
        int result = MoreThanHalfNum_Solution(array);
        System.out.println(result);
    }

    private static void test3() {
        int[] array = {};
        int result = MoreThanHalfNum_Solution(array);
        System.out.println(result);
    }
}

代码链接

剑指Offer代码-Java

posted @ 2019-08-19 12:34  这个世界~  阅读(104)  评论(0编辑  收藏  举报