記事のディレクトリ
-
- [5641.トラックの最大ユニット数(貪欲)](https://leetcode-cn.com/problems/maximum-units-on-a-truck/)
- [5642.食事数(列挙+ハッシュテーブル)](https://leetcode-cn.com/problems/count-good-meals/)
- [5643.配列を3つのサブ配列(プレフィックスと+ダブルポインター)に分割するためのスキームの数](https://leetcode-cn.com/problems/ways-to-split-array-into-three-subarrays/)
- [5644.サブシーケンスを取得するための最小操作数(貪欲+最長昇順サブシーケンス)](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/)
5641.トラックの最大ユニット数(貪欲)
class Solution {
public:
int maximumUnits(vector<vector<int>>& b, int m) {
sort(b.begin(), b.end(), [](vector<int> a, vector<int> b){
// lambda表达式
return a[1] > b[1];
});
int res = 0;
for(int i = 0;i < b.size() && m > 0; i ++ )
{
int cur = min(b[i][0],m);
res += cur * b[i][1];
m -= cur;
}
return res;
}
};
5642.食事数(列挙+ハッシュテーブル)
分析:
a [i] + a [j] = 2 k 2 ^ {k}2k、jを修正します。つまり、1〜jの数が2 k − a [j] 2 ^ {k} -a [j]を満たす数です。2k−a [ j ]、ハッシュテーブルを使用します。ここで2k 2 ^ {k}2k直接列挙、時間計算量O(22n)
class Solution {
public:
int countPairs(vector<int>& d) {
unordered_map<int,int> hash;
int res = 0, mod = 1e9 + 7;
for(auto x : d)
{
for(int i = 0;i <= 21; i ++ ) // 2的幂直接枚举,枚举到21!
{
int t = (1 << i) - x;
if(hash.count(t)) res = (res + hash[t]) % mod;
}
hash[x] ++;
}
return res;
}
};
5643.配列を3つのサブ配列(プレフィックスと+ダブルポインター)に分割するためのスキームの数
分析:
単調性があり、2つのダブルポインターが組み合わされており、境界を書くのは簡単ではありません。时间复杂度O(n)
class Solution {
public:
int waysToSplit(vector<int>& nums) {
int n = nums.size();
vector<int> s(n + 1);
for(int i = 1;i <= n ;i ++ ) s[i] = s[i - 1] + nums[i - 1]; // 前缀和下标从1开始
int res = 0, mod = 1e9 + 7;
for(int i = 3, j = 2, k = 2;i <= n; i ++ )
{
while(s[n] - s[i - 1] < s[i - 1] - s[j - 1]) j ++ ;
while(k + 1 < i && s[i - 1] - s[k] >= s[k]) k ++ ;
if(j <= k && s[n] - s[i - 1] >= s[i - 1] - s[j - 1] && s[i - 1] - s[k - 1] >= s[k - 1])
res = (res + k - j + 1) % mod;
}
return res;
}
};
5644.サブシーケンスを取得するための最小操作数(貪欲+最長昇順サブシーケンス)
分析:
最長共通部分列は最長昇順部分列に変換され、最長昇順部分列の長さは貪欲です、AcWing896。最長昇順部分列II [貪欲、バイナリ最適化]、時間の複雑さO(nlogn)
class Solution {
public:
int minOperations(vector<int>& target, vector<int>& arr) {
unordered_map<int,int> pos;
for(int i = 0; i< target.size();i ++ )
pos[target[i]] = i;
vector<int> a;
for(auto x : arr)
if(pos.count(x))
a.push_back(pos[x]);
// 贪心求最长上升子序列长度,模板背过!
int len = 0;
vector<int> q(a.size() + 1);
for(int i = 0;i < a.size(); i++ )
{
int l = 0, r = len;
while(l < r){
int mid = l + r + 1>> 1;
if(q[mid] < a[i]) l = mid;
else r = mid - 1;
}
len = max(len, r + 1);
q[r + 1] = a[i];
}
return target.size() - len;
}
};