算法学习(十一)数组中出现次数超过长度一半的数

数组中出现次数超过数组长度一半的 数字

题目描述:

给定 一个数组,找到数组中出现次数超过数组长度一半的数字,如数组 a[]= {0,1,2,1,1},输出为1

分析:

1,可以使用伴随数组b,遍历数组a,将值作为数组b的下标,将次数作为值,然后遍历数组b,找到次数超过一半的值,然后输出。时间复杂度为O(N),不过要增加空间复杂度。

2,我们可以先对数组进行排序,因为某个数字出现次数超过一半,所以在数组的N/2处,就一定是那个数字。时间复杂主要为排序的时间,使用快排O (N*logN).

3,有个数字出现的次数比其他的所有数组出现次数之和还要多,那么我们可以在遍历数组时,保存两个值,一个为数字,一个为次数,如果下一个数字和保存的数字不同,次数就减一,如果和保存的相同,次数就加一,如果次数为零,就保存下一个数字,且把次数重置为1,直到数组结束,保存的数字就是需要的。利用的就是数字的次数之和比其他的数字次数之和大,不同的就减,最后的次数肯定不为0。

例子: 0,1,2,1,1:

i = 0,result = 0,times = 1;

i = 1,a[1] != result,times–;times= 0;

i = 2,因为times = 0;result = a[2],times 重置为1;

i= 3,a[3] != result;times–;times = 0;

i = 4, result = 1;times = 1;

输出result = 1;

#include <iostream>
using namespace std;

int Find(int * data,int length)
{
    int result,times;
    times = 0;
    int i;
    for(i = 0;i<length;i++)
    {
        if(times == 0)
        {
            result = data[i];
            times =1;
        }
        else
        {
            if(result == data[i])
                times++;
            else
                times--;
        }
    }
    return result;
}
int main()
{
    int a[5] = {0,1,2,1,1};
    cout << Find(a,5) << endl;
    return 0;
}

数组中数字出现次数为长度一半的时候

这个时候,上面的方法就不行了,因为在遍历到最后一个数字时,times = 0,这个时候我们需要最后一个数,但是数组已经遍历完毕,保存可能是前面的某一个数。

如0,1,2,1

i = 0 ,result =0,times = 1;

i = 1,a[1]!= result;times–;times = 0;

i = 2 ,result = 2;times = 1;

i = 3,a[3] != result,times–;times = 0;

输出result = 2;但是我们需要时返回2的下一个数1。

如果是0,2,1,1

i = 0;result = 0;times= 1;

i = 1,a[1] != result ;times–;times= 0;

i = 2,result = 1,times = 1;

i = 3,a[3] == result;times++;times = 2;

输出result = 1;

我们会发现,实际上我们要判断的就是遍历到最后的时候保存的result和最后一个元素的比较,最后的输出从两个数之间选出。

我们可以针对最后一个元素,声明一个变量ntimes,遍历数组时,判断如果当前元素等于最后的元素,ntimes次数加一,最后直接判断,ntimes == N/2 ,如果true,说明最后一个元素就是,如果false,说明result中保存的数就是要找的。

int Find2(int * data,int length)
{
    int result,times,ntimes;
    times = ntimes = 0;
    int i;
    for(i = 0;i<length;i++)
    {
        if(data[i] == data[length-1])
            ntimes++;   //最后一个元素出现次数
        if(times== 0)
        {
            result = data[i];
            times = 1;
        }
        else
        {
            if(data[i] == result)
                times++;
            else
                times--;
        }
    }
    if(ntimes*2 == length)
        return data[length-1];
    else
        return result;
}
时间: 2024-08-03 08:30:37

算法学习(十一)数组中出现次数超过长度一半的数的相关文章

LeetCode 5126. 有序数组中出现次数超过25%的元素 Element Appearing More Than 25% In Sorted Array

地址 https://leetcode-cn.com/contest/biweekly-contest-15/problems/element-appearing-more-than-25-in-sorted-array/ 目描述给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25%.请你找到并返回这个整数 示例: 输入:arr = [1,2,2,6,6,6,6,7,10] 输出:6 提示: 1 <= arr.length <= 10^4 0 &

数组中出现次数超过数组长度一半的值

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.比如输入一个长度为18的数组{1,0,2,6,1,0,1,1,5,2,1,1,1,3,1,1,5,1}, 因为数组中数字1出现的次数超过数组的长度的一半,因此输出1. 1)最直接的办法是先把数组排序,那么超过一半的元素一定是数组最中间的元素. 2)再深入思考一下就会想到高速排序过程,利用partion找出index==middle时,index相应的值,而不必全然排序. 3)另外一种办法比較抽象,设一个变量保存当前值,设一个次数

数组中出现次数超过数组长度一半的数字

题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在则输出0. 解法一:若条件满足则这个数字在排序后的数组中必在最中间,所以把这个数字统计次数后和数字的一半长度比较后,若大于则满足条件,否则不满足.因涉及到快排,故时间复杂度时O(nlgn) class Solution { public: int MoreThanHalfNum_Solut

【Leetcode 数组】 有序数组中出现次数超过25%的元素(1287)

题目 给你一个非递减的?有序?整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25%. 请你找到并返回这个整数 示例: 输入:arr = [1,2,2,6,6,6,6,7,10] 输出:6 提示: 1 <= arr.length <= 10^4 0 <= arr[i] <= 10^5 解答 # class Solution: # def findSpecialInteger(self, arr): # d = {} # length = len(arr) #

[LeetCode169]Majority Element求一个数组中出现次数大于n/2的数

题目: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array. 思路:可以利用Dictionary将数组中每个数

寻找数组中出现次数超过一半的数字

[题 目]数组中有一个数字的出现次数超过了该数组长度的一半,找出这个数字. [思 路1]由于要寻找的数字的出现次数超过了数组长度的一半,所以如果将该数组排序,那么它的中位数必然是我们要寻找的数字,所以我们的任务就是对该数组进行排序,而性能最好的快速排序的时间复杂度为O(nlogn),我们可以直接借助库函数完成,由于其效率不是很高,所以这里就不再赘述. [思 路2]对于一个数组中的元素的次数的统计,最快的查找方法是什么?当然哈希表了!我们能不能建立哈希表呢,稍微思考,我们就可以发现,哈希表只适用于

剑指offer (29) 数组中出现次数超过一半或1/3或1/N的数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字 方法一:如果把这个数字排序,那么排序之后位于数组中间的数字一定就是出现次数超过数组长度一半的数字 这个数字就是统计学中的中位数,即长度为n的数组中第n/2大的数字 在数组中得到任意第k大数字,这一问题有O(n)解,注:这里第kth个元素,kth从1开始计数,并且重复元素不去重 (1) 直接sort排序,然后定位到索引为kth-1的元素 int FindKth1(std::vector<int>& num, int kt

编程算法 - 数组中出现次数超过一半的数字 代码(C)

数组中出现次数超过一半的数字 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 数组中有一个数字出现的次数超过数组长度的一半, 请找出这个数字. 1. 使用高速排序(QuickSort)的方法, 把中值(middle)和索引(index)匹配, 输出中值, 并检測是否符合要求. 2. 使用计数方法依次比較. 代码:  方法1: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */

算法之找出数组中出现次数大于n/m的元素

最经典的题目莫过于是: 在一个数组中找出出现次数超过n/2的元素?更进一步的,找出数组中出现次数大于n/3的所有元素? 注:这里有一个很重要的事实,那就是出现次数大于n/m的元素的个数至多为(m-1)个,比如出现次数大于n/3的至多只有两个. 关于这一类题目的解题思路,可以先讲一个游戏 称作 "俄罗斯方块".这里的规则是每一行的元素要完全不一样,一样的元素则总是在同一列,如果最下面的行已经被填满,那么消除最下面的行. 例如在数组 A = {7,3,3,7,4,3,4,7,3,4,3,4