剑指offer_数组---数组中出现次数超过一半的数

简介: 剑指offer_数组---数组中出现次数超过一半的数

题目描述

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

解题思路

1,第一种,超过一半的数必然出现在递增数组中间,先排序,然后统计中间值次数

2,第二种,遍历每一个数出现的次数,放到map里,然后用次数和len/2比较

3,第三种,利用数组的特性,超过一半的数出现的总次数比其它所有数出现总次数还多,这样我们在遍历数组的时候第一个值为result,次数为1,遇到相同的次数加1,遇到不同的减1,次数为0时,重复上述过程,最后得出的数即是持有股份最多的,不一定超过一半,然后我们在遍历统计它出现的次数,超过一半就是。

代码实现

/**
 * 
 */
package 数组;
import java.util.Arrays;
import java.util.HashMap;
/**
 * <p>
 * Title:MoreThanHalfNum
 * </p>
 * <p>
 * Description:
 * </p>
 * 
 * @author 田茂林
 * @data 2017年8月25日 下午5:13:34
 */
public class MoreThanHalfNum {
    // ===========================================================排序取中间值,时间复杂度nlogn
    public static int moreThanHalfNumSort(int[] array) {
        if (array == null || array.length < 1) {
            return -1;
        }
        int len = array.length;
        Arrays.sort(array);
        int num = array[len / 2];
        int count = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == num) {
                count++;
            }
        }
        if (count * 2 > len) {
            return num;
        } else {
            return 0;
        }
    }
    // ============================================================存放到hashmap里,时间复杂度为O(n),空间复杂度为O(n)
    public static int moreThanHalfNum(int[] array) {
        if (array == null || array.length < 1) {
            return -1;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        // 给数组中所有数字标记出现次数
        for (int i = 0; i < array.length; i++) {
            if (map.containsKey(array[i])) {
                map.put(array[i], map.get(array[i]) + 1);
            } else {
                map.put(array[i], 1);
            }
        }
        int len = array.length;
        for (int i = 0; i < map.size(); i++) {
            if (map.get(array[i]) > len / 2) {
                return array[i];
            }
        }
        return 0;
    }
    // ============================================================根据数组特点,时间复杂度O(n)
    public static int moreThanHalfNumSuper(int[] array) {
        if (array == null || array.length < 1) {
            return -1;
        }
        int len = array.length;
        int count = 1;
        int result = array[0];
        for (int i = 1; i < array.length; i++) {
            if (count == 0) {
                result = array[i];
                count = 1;
            }
            if (result == array[i]) {
                count++;
            } else {
                count--;
            }
        } // 最后持有count值的result可能就是超过一半的({ 1, 2, 3, 2, 2, 2, 5, 4, 2
            // },也有可能小于一半{1,2,2,3,4},但其是唯一候选人,股份最大的)
        // 遍历次数,如果次数超过一半,则说明是
        count = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == result) {
                count++;
            }
        }
        if (count * 2 > len) {
            return result;
        } else {
            return 0;
        }
    }
    public static void main(String[] args) {
        int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
        System.out.println(moreThanHalfNum(array));
        System.out.println(moreThanHalfNumSort(array));
    }
}


相关文章
|
算法
面试题:如何找出数组里出现次数超过总数1/3的数
如果你每次从nums中拿出3个不一样的数作为一组,肯定会出现两种情况。一,nums被取空了,那么nums中每个数出现次数最多占总次数的1/3,写代码很好处理吧!! 二,还有剩余,这个情况就复杂了,有可能剩余多个,但是……但是,最多只可能剩余两种数。 为什么? 3个不同的数凑一组才能删掉,所以不可能删掉超过1/3的数。所以超过1/3的数肯定被剩下来,但是,剩下来的俩数并不一定都是超过1/3的,这点额外注意。
69 1
|
6月前
|
算法 Java
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
70 0
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
|
6月前
剑指 Offer 39:数组中出现次数超过一半的数字
剑指 Offer 39:数组中出现次数超过一半的数字
34 0
【剑指offer】-数组汇总出现次数超过一半的数字-27/67
【剑指offer】-数组汇总出现次数超过一半的数字-27/67
|
6月前
剑指Offer LeetCode 面试题39. 数组中出现次数超过一半的数字
剑指Offer LeetCode 面试题39. 数组中出现次数超过一半的数字
32 0
剑指offer 40. 数组中出现次数超过一半的数字
剑指offer 40. 数组中出现次数超过一半的数字
78 0
|
算法 C++ Python
【每日算法Day 90】5种方法:求解数组中出现次数超过一半的那个数
【每日算法Day 90】5种方法:求解数组中出现次数超过一半的那个数
171 0
|
C++
13.数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
66 0
|
机器学习/深度学习 存储 算法
每日一练(20):数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
156 0