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

思想:这种题目一般都会要求o(n)的时间复杂度和o(1)的空间,目的就是为了不让你使用HashMap来统计计算。这里我们可以采用两两消除的思想去实现,例如一个数组arr为:1 2 2 3 2 1 2,那么我们把第一个元素arr[0]当作开始的元素k,它的出现次数count赋值为1,然后从第二个元素arr[1]开始往后遍历数组,如果arr[1] == k ,那么我们就把count++,如果不等于,我们就count--,如果count减为0了,那么重新把当前的元素arr[i]赋值给k,count重新赋值为1,然后继续这样比较。拿这个数组来说,最后k肯定为2,因为2出现的次数超过一半了。

public static void search(int[] arr) {
        if(arr.length == 0) return;
        int count = 1; //保存出现的次数
        int k = arr[0];
        for(int i = 1; i < arr.length; i++) {
            if(k == arr[i]) count++;
            else {
                count--;
                if(count == 0) {
                    k = arr[i];
                    count = 1;
                }
            }
        }
        count = 0;
        //也有可能没有元素超过一半,所以需要再次判断一下
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] == k) count++;
        }
        if(count > arr.length / 2) System.out.println(k);
        else System.out.println("未找到!");

    }

原文地址:https://www.cnblogs.com/neuzk/p/9487463.html

时间: 2024-11-04 14:18:30

数组中出现次数超过一半的数的相关文章

程序员面试题目总结--数组(三)【旋转数组的最小数字、旋转数组中查找指定数、两个排序数组所有元素中间值、数组中重复次数最多的数、数组中出现次数超过一半的数】

转!http://blog.csdn.net/dabusideqiang/article/details/38271661 11.求旋转数组的最小数字 题目:输入一个排好序的数组的一个旋转,输出旋转数组的最小元素. 分析:数组的旋转:把一个数组最开始的若干个元素搬到数组的末尾.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N).但这个思路没有利用输入数组

剑指offer——面试题29:数组中出现次数超过一半的数

题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]. 输出: 对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1. 解法一:基

经典面试题-数组中出现次数超过一半的数

[题意]:数组中有一个数字出现超过半数以上,找出这个数字. [解析]:一个数字超过半数以上,这是本题仅有的条件,所以,我们要从这个条件入手. 数字超过半数有什么特性呢?首先这个数字肯定是这些数的中位数.所以可以排序,然后找中位数. 但是时间复杂度为排序的O(n*logn),还可以再快吗? 现在有这么一个思路,我们知道,要求的这个数超过半数,那么两个不同的数我们消除,相同的累加, 最后一定能剩下那个超过半数的数字. 具体操作:用一个变量用来存当前剩下的数字,用一个变量做计数器.每次比较数字是否相同

47. 数组中出现次数超过一半的数字[Number appears more than half times]

[题目]:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字. 例如长度为9的数组{1,2,3,2,2,2,5,4,2}中次数超过了数组长度的一半的数字为2,而长度为8的数组{1,2,3,2,2,2,5,4}则为非法输入. [思路一]:先对数组进行排序,再遍历排序后的数组,统计每个数的次数,出现次数最大的数即为要找的数. 时间复杂度:O(nlgn)+ O(n)= O(nlgn):空间复杂度:O(1). [思路二]:先对数组进行排序,出现次数超过数组长度的一半的数必然是数组中间的那个数.

【剑指offer】十九,数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 分析:找数组中出现次数超过一半的数字,我们一半可以采用两种方法,一是使用快排,对数组进行排序,然后直接输出排序数组中间位置的数.第二种是使用HashMap<Integer,Integer>,key是数组中的数字,value为其在数组中出现的次数,顺序扫描数组,记录下数组出现的次数,输出大于数组长

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

数组中出现次数超过一半的数字 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 思路 若一个数出现的次数超过长度的一半,那么这个数出现的次数比数组里的其他数都多 用num来存数组的数,times来存次数,遍历数组,遇到一个数若跟num相等,times++,若不相等,times--,若times为零,则num存入下一个数,最后n

剑指offer系列源码-数组中出现次数超过一半的数字

题目1370:数组中出现次数超过一半的数字 时间限制:1 秒内存限制:32 兆特殊判题:否提交:2844解决:846 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,10

剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)

题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]. 输出: 对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1. 样例输入:

【C语言】统计数组中出现次数超过一半的数字

//统计数组中出现次数超过一半的数字 #include <stdio.h> int Find(int *arr, int len) { int num = 0; //当前数字 int times = 0; //当前数字出现的次数 int i = 0; for (i = 0; i<len; i++) { if (times == 0) { num = arr[i]; times = 1; } else if (arr[i] == num) times++; else times--; }