• 线性时间常数空间找到数组中数目超过n/5的所有元素


    问题描述:

    Design an algorithm that, given a list of n elements in an array, finds all the elements that appear more than n/3 times in the list. The algorithm should run in linear time ( n >=0 )
    You are expected to use comparisons and achieve linear time. No hashing/excessive space/ and don't use standard linear time deterministic selection algo

    解答:

    借鉴俄罗斯方块的玩法,先给个直观的例子。对于数组 4 3 3 2 1 2 3 4 4 7,按照类俄罗斯方块的玩法,当7要往下落的时候,屏幕上会呈现这个场景

    4
    4 3 2
    4 3 2 1 _

    当7落下时,获得了

    4
    4 3 2
    4 3 2 1 7

    此时最后一行元素数目满了(最后一行的大小为5),将其删除,继续落数字。直到所有数字都落下来了。此时数目超过n/5的元素一定在最后一行(因为假设数字a的个数超过n/5,删除操作最多执行了n/5次,所以最后必然a还在最后一行中)。但是,最后一行中的元素也有可能不是我们要的。此时需要扫描一下来确定。

    同样的算法对于任意的m(m为正整数)均适用。

    给出代码:

       1:  #include <iostream>
       2:  #include <map>
       3:  #include <algorithm>
       4:  typedef std::map<int, int> Map;
       5:   Map findOverNth(int arr[], int size, int n)
       6:  {
       7:      Map ret_map; 
       8:      typedef Map::value_type Elem; //pair<CONST int, int>
       9:      int total = 0;
      10:      std::for_each(arr, arr + size, [&, n](int val) 
      11:      {
      12:          auto ret_pair = ret_map.insert(Elem(val, 0));
      13:          ++(*ret_pair.first).second; ++ total;
      14:          if (ret_map.size() == n)
      15:              for (auto iter = ret_map.begin(); iter != ret_map.end(); )
      16:              {
      17:                  --(*iter).second; -- total;
      18:                  if ((*iter).second == 0)
      19:                      ret_map.erase(iter++);
      20:                  else
      21:                      iter++;
      22:              }
      23:      });
      24:      std::for_each(ret_map.begin(), ret_map.end(), [](Elem &elem) {elem.second = 0;});
      25:      std::for_each(arr, arr + size, [&ret_map](int val) {if (ret_map.find(val) != ret_map.end()) ret_map[val] ++;});
      26:      for (auto iter = ret_map.begin(); iter != ret_map.end(); )
      27:      {
      28:          if ((*iter).second <= size / n)
      29:              ret_map.erase(iter++);
      30:          else 
      31:              iter++;
      32:      }
      33:      return ret_map;
      34:  }
      35:  using namespace std;
      36:  int main()
      37:  {
      38:      //int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
      39:      int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1};
      40:      auto a_map = findOverNth(arr, sizeof(arr)/sizeof(int), 4);
      41:      cout<<sizeof(arr)/sizeof(int)<<endl;
      42:      //cout<<a_map.size()<<endl;
      43:      for each(auto elem in a_map)
      44:      {
      45:          cout<<elem.first<<" "<<elem.second<<endl;
      46:      }
      47:  }
  • 相关阅读:
    Qt 资料大全
    Node.js+websocket+mongodb实现即时聊天室
    win系统下nodejs安装及环境配置
    nginx关于 error_page指令详解.md
    移动前端开发之viewport,devicePixelRatio的深入理解
    Iphone各个型号机型的详细参数,尺寸和dpr以及像素
    H5前端的关于像素解释
    从Pc转向H5开发遇到的适配问题思考
    Safari无痕模式下,storage被禁用问题
    滴滴开源 Vue 组件库— cube-ui
  • 原文地址:https://www.cnblogs.com/xubenben/p/3382610.html
Copyright © 2020-2023  润新知