心情
题目在此
双周赛都补题
第一题(差的绝对值为 K 的数对数目)
class Solution {
public:
int countKDifference(vector<int>& nums, int k) {
int le = nums.size(),ans = 0;
for (int i = 0; i < le ; i ++)
for (int j = i + 1; j < le; j ++)
if (abs(nums[i]-nums[j])==k)ans++;
return ans;
}
};
第二题(从双倍数组中还原原数组)
也不难
class Solution {
public:
int cnt[200100];
vector<int> findOriginalArray(vector<int>& c) {
int le = c.size();
vector<int> res;
if (le % 2)return res;
for (int i = 0; i < le; i ++) cnt[c[i]]++;
if (!(cnt[0]%2)&&cnt[0]){
for (int i = 0; i < cnt[0]/2; i ++)res.push_back(0);
}else if (cnt[0])return res;
for (int i = 1; i < 100100; i ++){
if (cnt[i]&&cnt[i*2]&&cnt[i]<=cnt[i*2]){
for (int j = 0; j < cnt[i]; j ++)res.push_back(i);
cnt[i*2]-=cnt[i];
}
}
if (res.size() != le/2)res.clear();
return res;
}
};
第三题(出租车的最大盈利)
D P DP DP
typedef long long ll;
class Solution {
public:
ll dp[100100];
ll maxTaxiEarnings(int n, vector<vector<int>>& r) {
vector<vector<pair<int,int>>> v(n+1);
int le = r.size();
for (int i = 0; i < le; i ++)v[r[i][1]].push_back({r[i][0],r[i][1] - r[i][0] + r[i][2]});
for (int i = 2; i <= n; i ++){
dp[i] = dp[i-1];//不在第i个结点停车
for (auto p:v[i]){ //在第i个结点停车
dp[i] = max(dp[i],dp[p.first] + p.second); //找到一个最大值
}
}
return dp[n];
}
};
第四题(使数组连续的最少操作数)
不
错
的
双
指
针
不错的双指针
不错的双指针
最
小
操
作
数
=
n
−
最
大
保
留
的
数
字
数
量
最小操作数=n - 最大保留的数字数量
最小操作数=n−最大保留的数字数量
class Solution {
public:
int minOperations(vector<int>& nums) {
sort(nums.begin(),nums.end());
int n = nums.size();
int ma = 0;
unordered_map<int,int> ump; //去重
for (int i = 0,j = 0; i < n; i ++){
//以i为起点,数组里最多可以留下多少数字 以i为起点,那么最大的那个数字是nums[i] + n - 1
for (; j < n && nums[j] <= nums[i] + n - 1; j ++) ump[nums[j]]++;
ma = max(ma,int(ump.size()));
ump[nums[i]] --; //计算下一个起点,此点数量减 1
if (ump[nums[i]] == 0)ump.erase(nums[i]);//如果没有nums[i]这个数字的记录,要把它从集合中删除
}
return n - ma;
}
};