1.咒语和药水的成功对数
题目

解析
- 注意点:函数引用数组要加 &,不然会超时;
- 时间复杂度:O((n + m) * log m;空间复杂度:O(1);
代码
class Solution {int lower_bound(vector<int>& potions,double target){int l = 0,r = potions.size() - 1;while(l <= r){int mid = l + (r - l) / 2;if(potions[mid] >= target){r = mid - 1;} else {l = mid + 1;}}return l;}public:vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {// 时间复杂度:O(nlog n)// 空间复杂度:O(1)vector<int> ans(spells.size(),0);sort(potions.begin(),potions.end());for(int i = 0;i < spells.size();i ++){int start = lower_bound(potions,(double)success / spells[i]);ans[i] = potions.size() - start;}return ans;}
};
2.和有限的最长子序列
题目

解析
- nums 数组可以排序,不影响子序列长度,本题需要一个额外数组记录前缀和;
- 时间复杂度:O((n + m) * log n;空间复杂度:O(n);
代码
class Solution {int lower_bound(vector<int>& s,int target){int l = 0,r = s.size() - 1;while(l <= r){int mid = l + (r - l) / 2;if(s[mid] >= target){r = mid - 1;} else {l = mid + 1;}}return l;}public:vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {// 时间复杂度:O((n + m) * log n)// 空间复杂度:O(n)int n = nums.size(),m = queries.size();vector<int> ans(m,0);sort(nums.begin(),nums.end());// 排序不影响子序列和vector<int> s(n);// 前缀和数组s[0] = nums[0];for(int i = 1;i < n;i ++) s[i] = s[i - 1] + nums[i];for(int i = 0;i < m;i ++){int x = lower_bound(s,queries[i] + 1) - 1;ans[i] = x + 1;}return ans;}
};
3.统计公平数对的数目
题目

解析
代码
class Solution {int lower_bound(vector<int>& nums,int target){int l = 0,r = nums.size() - 1;while(l <= r){int mid = l + (r - l) / 2;if(nums[mid] >= target){r = mid - 1;} else {l = mid + 1;}}return l;}public:long long countFairPairs(vector<int>& nums, int lower, int upper) {// 时间复杂度:O(nlog n)// 空间复杂度:O(1)int n = nums.size();long long ans = 0;sort(nums.begin(),nums.end());for(int i = 0;i < n;i ++){int start = lower_bound(nums,lower - nums[i]);int end = lower_bound(nums,upper - nums[i] + 1) - 1;if(start > i) ans += end - start + 1;// 左边界在 i 右边else if(end > i) ans += end - i;// 边界包含 i}return ans;}
};