2022.3.13LeetCode第284场周赛
2200. 找出数组中的所有 K 近邻下标
思路
二分:找出nums
中所有值为key
的下标,对于每个元素,寻找前后两个最近的下标,若其中一个小于等于k
,则该元素满足条件
代码
class Solution {
public:
vector<int> findKDistantIndices(vector<int>& nums, int key, int k) {
int n = nums.size();
vector<int> ans;
vector<int> b;
for (int i = 0; i < n; i ++ ) {
if (nums[i] == key)
b.push_back(i);
}
for (int i = 0; i < n; i ++ ) {
int t = lower_bound(b.begin(), b.end(), i) - b.begin();
int res = 1e9;
if (t < b.size())
res = b[t] - i;
if (t > 0)
res = min(res, i - b[t - 1]);
if (res <= k)
ans.push_back(i);
}
return ans;
}
};
2201. 统计可以提取的工件
思路
模拟+哈希:将所有要挖的单元格存储下来,枚举所有工件判断是否能被提取出来
代码
class Solution {
public:
int digArtifacts(int n, vector<vector<int>>& artifacts, vector<vector<int>>& dig) {
set<pair<int, int>> se;
for (auto i : dig) {
se.insert({i[0], i[1]});
}
int ans = 0;
for (auto i : artifacts) {
int r1 = i[0], c1 = i[1], r2 = i[2], c2 = i[3];
bool f = true;
for (int i = r1; i <= r2 && f; i ++ )
for (int j = c1; j <= c2; j ++ ) {
if (!se.count({i, j})) {
f = false;
break;
}
}
if (f)
ans ++ ;
}
return ans;
}
};
2202. K 次操作后最大化顶端元素
思路
分类讨论
- 当
nums
的大小为1时,每步操作只有一种选择,k
为偶数时,栈里存在1个元素;k
为奇数时,栈中没有元素 - 当
nums
的大小大于1时,栈顶元素可能存在以下情况:nums
的前k - 1
个元素的最大值 (取出前k
个数,再放回最大值)nums
的第k + 1
个元素(取出前k
个数)
代码
class Solution {
public:
int maximumTop(vector<int>& nums, int k) {
int n = nums.size();
if (n == 1 && k % 2) return -1;
int ans = 0;
for (int i = 0; i + 1 < k && i < n; i ++ )
ans = max(ans, nums[i]);
if (k < n)
ans = max(ans, nums[k]);
return ans;
}
};
2203. 得到要求路径的最小带权子图
思路
堆优化的dijkstra+枚举中间节点
所有从src1
和src2
到dest
的子图,一定包含某一中间节点x
,所包含的路径为从src1
到x
,src2
到x
,和x
到dest
。在图中作三次dijkstra最短路,其中x
在反图中求,再枚举所有x
求边权和的最小值
证明:若最优解中src1
到dest
和src2
到dest
两条路径的第一个交点是x
,则一起从x
到dest
是最优的,否则其他路径的边权和一定大于最短路的边权和
代码
typedef long long ll;
typedef pair<ll, int> PLI;
class Solution {
public:
vector<vector<pair<int, int>>> g;
vector<vector<pair<int, int>>> ug;
int n;
vector<ll> di(int s, vector<vector<pair<int, int>>> g) {
vector<ll> d(n, 1e18);
vector<bool> st(n, false);
priority_queue<PLI, vector<PLI>, greater<PLI>> heap;
d[s] = 0;
heap.push({0, s});
while (heap.size()) {
auto t = heap.top();
heap.pop();
int v = t.second;
ll dis = t.first;
if (st[v]) continue;
st[v] = true;
for (auto i : g[v]) {
int j = i.first, w = i.second;
if (d[j] > dis + w) {
d[j] = dis + w;
heap.push({d[j], j});
}
}
}
return d;
}
long long minimumWeight(int _n, vector<vector<int>>& edges, int src1, int src2, int dest) {
n = _n + 1;
g.resize(n);
ug.resize(n);
for (auto i : edges) {
g[i[0]].push_back({i[1], i[2]});
}
for (auto i : edges) {
ug[i[1]].push_back({i[0], i[2]});
}
vector<ll> d1, d2, d3;
d1 = di(src1, g);
d2 = di(src2, g);
d3 = di(dest, ug);
ll ans = 1e18;
for (int i = 0; i < n; i ++ ) {
if (d1[i] != 1e18 && d2[i] != 1e18 && d3[i] != 1e18)
ans = min(ans, d1[i] + d2[i] + d3[i]);
}
return ans == 1e18 ? -1 : ans;
}
};