zoukankan      html  css  js  c++  java
  • 第2章 数字之魅——数字中的技巧2.3

    2.3寻找发帖“水王”

    问题:求在一个ID列表中出现次数超过一半的ID。

    对于该问题:一个比较直接的想法就是直接统计。统计每个ID出现的次数。然后寻找该数组中最大的数值。从而找出它的ID。

    统计需要N,并且空间上要2*N(而且这里必须保证ID不能是小数而且ID是连续的)。然后对于寻找最大元素。一种是分治。log2 N。一种是建个最大堆。(复杂度)

    当然还有一种就是打擂台。N。

    总体上需要N+N。或者N+log2 N

    另外一种想法是排序后找中间的元素。因为大过一半。所以必然是该ID。利用快排 N*log2 N 很省事。

    而且这个可以推广到那个扩展问题。当元素是大过1/4的时候。那我们只要找下标在3/4的时候即可。

    在编程之美上面,有一个十分巧妙的想法。就是删除2个不同的ID。用来减小问题的规模。(减小问题规模这种思想是我们应该要具备的,这算是一种消元法吧?)

    同时这个想法也是比较容易操作的。而且空间和时间上都有很大的提升,空间是常数的。时间是N的级别。

    当初我不解并且觉得神奇之处在于不同的ID如何实现?一个直观的想法就是用一个 int 型数来保存之前遇到的ID。可是继续思考下去这并不方便。

    那就是维护当前的id。如果下一个遇到的不是这个id就抵消。如果是的话就统计这个id已经出现了2次。最后id保存的一定是出现最多次数的ID。

    //这里假设 ID 是 int 型的,就不用定义Type了, 编程之美上用Type。当然书上更好。
    int Find(int ID,int N)
    {
        /*
        id 就是当前存储的id
        nTimes 代表这个id出现的次数
        */
        int id;
        int nTimes,i;
        nTimes = 0;
        for(i=0;i<N;i++)
        {
            if(nTimes==0)  
            {
                nTimes = 1;
                id = ID[i];
            }
            else
            {
                if(id == ID[i])
                {
                    nTimes ++;
                }
                else
                {
                    nTimes --;
                }
            }
        }
        return id;
    }
    编程之美——优美思想


    反思:这一节的星数是一颗。但是我觉得这里面包含了缩小问题规模的重要思想。正如解决一个难题。我们可以把大化小。解小。而这种缩小问题规模的方法,在编程之美中是屡试不爽的。从求数组的最大值的那一篇章也可以了解到。从而引出了一个重要的算法思想。分治。

  • 相关阅读:
    jpeg 文档格式
    gif 文件格式
    firefox前世今生
    png 文档格式
    字符'\xe5\x8c\x97\xe4\xba\xac\xe6\x96\xb0\xe5\x8d\x8e\xe7\x94\xb5\xe8\x84\x91\xe5\xad\xa6\xe6\xa0\xa1' 转为汉字
    SQL server 报错:
    encode 与 decode
    Octave 作图 无响应
    qmake建工程
    urlparse (scheme、netloc、path等)
  • 原文地址:https://www.cnblogs.com/Milkor/p/4351028.html
Copyright © 2011-2022 走看看