zoukankan      html  css  js  c++  java
  • 找出数列中个数大于总数一半的元素(编程之美2.3)

    案例

    数列3, 2, 3, 1, 3, 3, 2, 3中,3就是个数大于总数大于一半的元素。

    思路一

    对数列排序,再扫描一边,找出元素个数超过一半的元素。此时需要排序,同时需要记录每个元素出现个数,费时、费空间。

    思路二

        对于排好序的数列,假设总数为N,那么N/2位置的那个数必定为所求之数,这就不需要记录每个元素的个数。

    思路三

         对于数列,不用排序。对于其中的任意两个不同的元素,去除之后,原来那个个数大于总数一半的元素个数仍然是大于剩下元素的一半的。利用该特性遍历一遍数列就可以找出这个总数大于一半的那个元素。

        具体的实施,不用每次去这些数中去找不同的两个数,只需记录当前候选目标值can,与此对应的为其个数num,目前访问的元素为cur

    • num==0: can=cur, num=1
    • num!=0 && can = cur: num++
    • num!=0 && can != cur: num--

    如果现在访问的元素与目标值相同,那么num++,不同num--;如果num=0,那么把候选元素改为此元素,并且赋值num=1

    图示

    通过简单分析可以得知

    • 当总素为偶数时,Num最终至少为2
    • 当总数为奇数时,Num最终至少为1

    参考代码

    #include<iostream>
    using namespace std;
    
    int Find(int a[], int N)
    {
        int count = 0;
        int candidate = 0;
        for(int i = 0; i < N; ++i)
        {
            if(count == 0)
            {
                candidate = a[i];
                count = 1;
            }
            else if(candidate == a[i])
                    ++count;
            else
                    --count;
            }
        return candidate;
    }
    
    int main()
    {
        int a[] = {3, 2, 3, 1, 3, 3, 2, 3};
        int val = Find(a, sizeof(a) / sizeof(int));
        cout << "Result:" << val << endl;
    }

    结果

    Result:3

    性能

    时间复杂度O(n), 空间复杂度O(1)

    扩展

    3个人发帖超过n/4,找粗这三个人

    void Find(Type* ID, int N, Type candidate[3])
    {
        Type ID_NULL;//定义一个不存在的ID
        int nTimes[3], i;
        nTimes[0]=nTimes[1]=nTimes[2]=0;
        candidate[0]=candidate[1]=candidate[2]=ID_NULL;
        for(i = 0; i < N; i++)
        {
            if(ID[i]==candidate[0])
            {
                 nTimes[0]++;
            }
            else if(ID[i]==candidate[1])
            {
                 nTimes[1]++;
            }
            else if(ID[i]==candidate[2])
            {
                 nTimes[2]++;
            }
            else if(nTimes[0]==0)
            {
                 nTimes[0]=1;
                 candidate[0]=ID[i];
            }
            else if(nTimes[1]==0)
            {
                 nTimes[1]=1;
                 candidate[1]=ID[i];
            }
            else if(nTimes[2]==0)
            {
                 nTimes[2]=1;
                 candidate[2]=ID[i];
            }
            else
            {
                 nTimes[0]--;
                 nTimes[1]--;
                 nTimes[2]--;
             }
        }
        return;
    }
  • 相关阅读:
    python3.6入门到高阶(全栈) day013-014 内置函数
    python3.6入门到高阶(全栈) day012 生成器
    PHP数组基本排序算法和查找算法
    02 LAMP环境下安装WordPress
    02 React Native入门——Hello World
    01 React Native入门——环境安装部署
    02 “响应式Web设计”——媒体查询
    01 “响应式Web设计”——概述
    01 Portal for ArcGIS 10.7安装部署教程(windows环境)
    06 spring boot入门——AJAX请求后台接口,实现前后端传值
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3563877.html
Copyright © 2011-2022 走看看