给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。
n == citations.length
1 <= n <= 5000
0 <= citations[i] <= 1000
本题题意就是给你一个数组,找到最大的h,使得数组中至少有h个数都大于等于h。考虑到本题的n较小,因此如果使用排序的话复杂度也只是\(nlogn\),不会超时。因此先把数组从小到大排序,可以看出h最大就是数组的长度,因此我们可以从最大值开始判断,i从0开始,如果此时nums[i]>=h
,说明至少有h个数都大于等于h,直接输出答案,因为我们是从大到小枚举h。
class Solution {
public:
int hIndex(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
int h = n;
for(int i = 0;i < n;i ++ ){
if(nums[i] >= h) return h;
else h --;
}
return h;
}
};
本题还可以采用二分,因此h的值只会在1-n,因此我们在1-n之间二分,令mid=l + r + 1 >> 2
,如果此时mid满足由mid个数都大于等于mid,我们令左区间l=mid;否则令右区间r=mid - 1。
class Solution {
public:
int hIndex(vector<int>& nums) {
int n = nums.size();
int l = 0, r = n;
while(l < r){
int mid = l + r + 1 >> 1;
if(check(nums, mid)) l = mid;
else r = mid - 1;
}
return l;
}
bool check(vector<int> nums, int h){
int cnt = 0;
for(int i = 0;i < nums.size();i ++ ){
if(nums[i] >= h) cnt ++;
}
if(cnt >= h) return true;
return false;
}
};
实现RandomizedSet 类:
RandomizedSet() 初始化 RandomizedSet 对象
bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。
\(-2^{31} <= val <= 2^{31} - 1\)
最多调用 insert、remove 和 getRandom 函数 2 * 105 次
在调用 getRandom 方法时,数据结构中 至少存在一个 元素。
本题就是模拟,直接根据题意一步步操作即可。首先对于插入,定义哈希表用来存储每个插入元素的下标和判断该元素是否存在,再定义一个数组用来存储元素,方便后面输出随机一个元素;对于删除,和插入类似,不过需要删除数组和哈希表的对应元素;对于随机一个元素,直接rand即可。
class RandomizedSet {
public:
unordered_map<int, int> hash;
vector<int> arr;
int cnt = 0;
RandomizedSet() {
}
bool insert(int val) {
auto it = hash.find(val);
if(it == hash.end()){
hash[val] = cnt ++;
arr.push_back(val);
return true;
}
return false;
}
bool remove(int val) {
auto it = hash.find(val);
if(it != hash.end()){
int item = it->second;
arr[item] = arr.back();
hash[arr[item]] = item;
arr.pop_back();
cnt --;
hash.erase(val);
return true;
}
return false;
}
int getRandom() {
return arr[rand() % cnt];
}
};
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet* obj = new RandomizedSet();
* bool param_1 = obj->insert(val);
* bool param_2 = obj->remove(val);
* int param_3 = obj->getRandom();
*/
总结,整体比较简单,就是需要一点小技巧。
标签:150,return,val,nums,int,RandomizedSet,mid,---,004 From: https://www.cnblogs.com/timeac-coder/p/18125817