zoukankan      html  css  js  c++  java
  • 97 子数组中占绝大多数的元素(1157)

    作者: Turbo时间限制: 1S章节: 线段树

    晚于: 2020-09-09 12:00:00后提交分数乘系数50%

    问题描述 :

    实现一个 MajorityChecker 的类,它具有下述两个 API:

    1、MajorityChecker(int[] arr) :用给定的数组 arr 来构造一个 MajorityChecker 的实例。

    2、int query(int left, int right, int threshold) 

    参数为:

                0 <= left <= right < arr.length ,其中arr.length表示数组 arr 的长度。

                2 * threshold > right - left + 1,也就是说阈值 threshold 始终比子序列长度的一半还要大。

    功能:每次查询返回在 arr[left], arr[left+1], ..., arr[right] 中至少出现threshold 次数的元素,如果不存在这样的元素,就返回 -1。

    说明:由于threshold 比子序列长度的一半还要大,因此,不可能存在两个元素都出现了threshold 次。

    示例:

    MajorityChecker majorityChecker = new MajorityChecker([1,1,2,2,1,1]);

    majorityChecker.query(0,5,4); // 返回 1

    majorityChecker.query(0,3,3); // 返回 -1

    majorityChecker.query(2,3,2); // 返回 2

    可使用以下main函数:

    int main()

    {

        int n,a,m,left,right, threshold;

        vector<int> arr;

        cin>>n;

        for(int i=0; i<n; i++)

        {

            cin>>a;

            arr.push_back(a);

        }

        MajorityChecker mc(arr);

        cin>>m;

        for(int i=0; i<m; i++)

        {//在IDE中运行时,输入和输出会交错,这是正常现象

            cin>>left;

            cin>>right;

            cin>>threshold;

            int res=mc.query(left, right, threshold) ;

            cout<<res<<" ";

        }

    }

    输入说明 :

    首先输入arr数组的长度n,然后输入n个整数,表示arr中的元素

    再输入查询的次数m,

    然后输入m行,每行是一个查询的参数left, right, threshold,用空格分隔。

    提示:

    1 <= n <= 20000

    1 <= arr[i] <= 20000

    对于每次查询,0 <= left <= right < n

    对于每次查询,2 * threshold > right - left + 1

    m<=10000

    输出说明 :

    输出m个整数,对应m次查询的结果,每个整数后有一个空格。

    输入范例 :

    输出范例 :

    #include <iostream>
    #include <string>
    #include <vector>
    #include <unordered_map>
    #include <algorithm>
    using namespace std;
    class MajorityChecker {
    public:
        unordered_map<int, vector<int>> map;
        
        MajorityChecker(vector<int>& arr) {
          for (auto i = 0; i < arr.size(); ++i) map[arr[i]].push_back(i);
        }
        
        int query(int left, int right, int threshold) {
          for (auto &temp : map) {
            if (temp.second.size() < threshold) continue;
            auto m= lower_bound(begin(temp.second), end(temp.second), left);
            auto n = upper_bound(begin(temp.second), end(temp.second), right);
            if (n - m >= threshold) return temp.first;
          }
          return -1;
        }
    };
    int main()
    {
        int n,a,m,left,right, threshold;
        vector<int> arr;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>a;
            arr.push_back(a);
        }
        MajorityChecker mc(arr);
        cin>>m;
        for(int i=0; i<m; i++)
        {//在IDE中运行时,输入和输出会交错,这是正常现象
            cin>>left;
            cin>>right;
            cin>>threshold;
            int res=mc.query(left, right, threshold) ;
            cout<<res<<" ";
        }
    }
    //lower_bound(起始地址,结束地址,要查找的数值) 返回的是数值 第一个 出现的位置。
    //upper_bound(起始地址,结束地址,要查找的数值) 返回的是数值 最后一个 出现的位置。
    //binary_search(起始地址,结束地址,要查找的数值) 返回的是是否存在这么一个数,是一个bool值。
    /*
    int ia[] = {0,1,2,3,4,5,6,7,8,9};
    int *beg = begin(ia);
    int *last  = end(ia);
    上面代码中begin()返回的是数组首元素的指针,
    end()返回的是尾元素的下一位置的指针。
    这是C++11 为我们提供的两个非常方便的定位数组指针的函数。
    
    */
  • 相关阅读:
    Linux线程信号
    有理想的程序员必须知道的15件事
    Linux下 mplayer 使用手册
    Winxp下 gvim 编程环境搭建
    在WPF中弹出右键菜单时判断鼠标是否选中该项
    F#基本类型——Discriminated Unions
    在WPF的TreeView中实现右键选定
    WPF TreeView tools
    F#基本类型——Structure
    增强了一下DownloaderPlus的视频转换功能
  • 原文地址:https://www.cnblogs.com/zmmm/p/13675711.html
Copyright © 2011-2022 走看看