题目
-
- 袋子里最少数目的球
- 袋子里最少数目的球
-
一个图中连通三元组的最小度数
思路与算法
- 经典二分搜索题目,套模板,主要搞清楚如何检查遍历的每一个数是否符合不大于maxOperations即可。
- 貌似可以直接暴力结束,直接统计是否连接和出入度即可。题目给了n的上限是400,典型的3次复杂度的极限值。也间接说明可以暴力检索三元组。
代码实现
-
- 袋子里最少数目的球
class Solution {
public int minimumSize(int[] nums, int maxOperations) {
int low = 1;
int high = 1000000001;
while (low + 1 < high) {
int mid = low + (high - low) / 2;
if (check(nums,mid,maxOperations)) {
high = mid;
} else {
low = mid;
}
}
if (check(nums,low,maxOperations)) {
return low;
}
return high;
}
public boolean check(int[] balls,int penalty,int maxOperations){
int res = 0;
for (int i: balls) {
res += i / penalty;
if (i % penalty == 0) {
res -= 1;
}
if (res > maxOperations) {
return false;
}
}
return true;
}
}
- 一个图中连通三元组的最小度数
class Solution {
public:
int minTrioDegree(int n, vector<vector<int>>& edges) {
int ans = INT_MAX;
vector<int> Degrees(n);
vector<vector<bool>> Connected(n,vector<bool>(n));
// 统计是否连接以及出入度
for (auto &edge : edges) {
Connected[edge[0] - 1][edge[1] - 1] = true;
Connected[edge[1] - 1][edge[0] - 1] = true;
Degrees[edge[0] - 1]++;
Degrees[edge[1] - 1]++;
}
// 直接遍历寻找三元组即可
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
// 剪枝:直接砍掉两两不相连的
if ( !Connected[i][j] ){
continue;
}
for (int k = j + 1; k < n; ++k) {
// 如果全部两两相连
if (Connected[i][k] && Connected[j][k]) {
ans = min(ans,Degrees[i] + Degrees[j] + Degrees[k] - 6);
}
}
}
}
return ans == INT_MAX ? -1 : ans;
}
};
写在最后
- 在家的最后几天,好好陪家里人