zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    numpy学习(将条件逻辑表述为数组运算)
    numpy学习(利用数组进行数据处理)
    numpy学习(通用函数:快速的元素级数组函数)
    numpy学习(数组转置和轴对换)
    numpy学习(花式索引)
    关于C++中的虚拟继承的一些总结
    adb常用命令
    进程隐藏的方法
    Microsoft Detours 2.1简介
    ebay如何确定同一电脑登陆了多个账号,以及同一账号登陆过多台电脑
  • 原文地址:https://www.cnblogs.com/haoworld/p/offer39-shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-b.html
Copyright © 2011-2022 走看看