1157. Online Majority Element In Subarray

问题:

给定数组,求给定区间中,出现次数>=threshold的元素值。

Example:
MajorityChecker majorityChecker = new MajorityChecker([1,1,2,2,1,1]);
majorityChecker.query(0,5,4); // returns 1
majorityChecker.query(0,3,3); // returns -1
majorityChecker.query(2,3,2); // returns 2
 

Constraints:
1 <= arr.length <= 20000
1 <= arr[i] <= 20000
For each query, 0 <= left <= right < len(arr)
For each query, 2 * threshold > right - left + 1
The number of queries is at most 10000

  

解法:

随机值法:【参考解说

给定一个区间,显然可以尝试从中随机选择数字,

然后判断该数字是否是该区间中的majority(需要用到Index Search Array)。

如果经过多次随机都找不到,则说明不存在majority。

通过多次随机,可以将错误概率降低到非常小,可以算是一种成功的算法。

 

构建一个map:coutarr

key:原数组的元素值

value:所在index(会存在多个,因此为一个vector<int>)

对于猜测的随机值value:

在map:coutarr中找到该元素值,得到元素值的所有index序列,

在这个序列中找,在给定区间(left, right)内,有多少个index。

这里使用到

auto l=lower_bound(it->second.begin(), it->second.end(), left);
auto r=upper_bound(it->second.begin(), it->second.end(), right);

在给定vector区间(it->second.begin(), it->second.end())中,

lower_bound:找到第一个值>=left的元素index返回。

upper_bound:找到第一个值>right的元素index返回。

则 r-l 即为值value在给定区间(left, right)内,出现的次数。

若这个次数>=threshold,则猜测正确。

 

代码参考:

 1 class MajorityChecker {
 2 public:
 3     vector<int> arrv;//{pos,value}
 4     unordered_map<int, vector<int>>coutarr;
 5     int coutValue(int left, int right, int value){
 6         auto it = coutarr.find(value);
 7         if(it==coutarr.end()) return 0;
 8         auto l=lower_bound(it->second.begin(), it->second.end(), left);
 9         auto r=upper_bound(it->second.begin(), it->second.end(), right);
10         return r-l;
11     }
12     MajorityChecker(vector<int>& arr) {
13         arrv=arr;
14         for(int i=0; i<arr.size(); i++){
15             coutarr[arr[i]].push_back(i);
16         }
17         srand(time(0));
18     }
19     
20     int query(int left, int right, int threshold) {
21         for(int i=0; i<20; i++){
22             int idx = random() % (right-left+1) +left;
23             int cout = coutValue(left, right, arrv[idx]);
24             if(cout>=threshold) return arrv[idx];
25         }
26         return -1;
27     }
28 };
29 
30 /**
31  * Your MajorityChecker object will be instantiated and called as such:
32  * MajorityChecker* obj = new MajorityChecker(arr);
33  * int param_1 = obj->query(left,right,threshold);
34  */

 

上一篇:简易平衡树


下一篇:模拟实现js的bind方法