513. 找树左下角的值
207. 课程表
373. 查找和最小的K对数字
1889. 装包裹的最小浪费空间
- 找树左下角的值https://leetcode-cn.com/problems/find-bottom-left-tree-value/
// 经典广搜
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
vector<int> cnt;
while (!que.empty()) {
cnt.clear();
int len = que.size();
while (len--) {
TreeNode* node = que.front();
cnt.push_back(node->val);
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return cnt[0];
}
};
- 课程表https://leetcode-cn.com/problems/course-schedule/
// 拓扑排序模板题
// dfs 所有节点分为三个状态 0 未访问 1 访问未回溯,2 访问且回溯
// 如果dfs的节点访问到1,说明有环,返回false
// 访问到节点v为2,当前节点不会影响v的拓扑结构 因此不用对齐做任何操作
class Solution {
public:
bool canFinish(int num, vector<vector<int>>& prerequisites) {
vector<vector<int>> edge(num);
vector<int> indegree(num, 0);
vector<int> vis(num, 0);
for (auto& p : prerequisites) {
edge[p[1]].push_back(p[0]);
indegree[p[0]]++;
}
vector<int> cnt;
for (int i = 0; i < num; i++) {
if (indegree[i] == 0) {
if (!dfs(edge, i, vis, cnt)) {
return false;
}
}
}
if (cnt.size() < num) return false;
reverse(cnt.begin(), cnt.end());
return true;
}
bool dfs(vector<vector<int>>& edge, int course, vector<int>& vis, vector<int>& cnt) {
if (vis[course] == 2) return true;
if (vis[course] == 1) return false;
vis[course] = 1;
for (int i = 0; i < edge[course].size(); i++) {
if (!dfs(edge, edge[course][i], vis, cnt)) {
return false;
}
}
vis[course] = 2;
cnt.push_back(course);
return true;
}
};
// bfs 记录入度,每次弹出节点减少相邻节点的入度,取入度为0的节点加入队列
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> indegree(numCourses, 0);
vector<vector<int>> edge(numCourses);
for (auto& pre: prerequisites) {
edge[pre[1]].push_back(pre[0]);
indegree[pre[0]]++;
}
queue<int> que;
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
que.push(i);
}
}
int cnt = 0;
while (!que.empty()) {
int item = que.front();
que.pop();
cnt++;
for (int i = 0; i < edge[item].size(); i++) {
if (--indegree[edge[item][i]] == 0) {
que.push(edge[item][i]);
}
}
}
return cnt == numCourses;
}
};
- 查找和最小的K对数字https://leetcode-cn.com/problems/find-k-pairs-with-smallest-sums/
// 类似于双指针
class Solution {
public:
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
if (nums1.empty() || nums2.empty() || k <= 0) return {};
auto cmp = [&nums1, &nums2](pair<int, int> a, pair<int, int> b) {
return nums1[a.first] + nums2[a.second] > nums1[b.first] + nums2[b.second];
};
vector<vector<int>> ans;
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pque(cmp);
// 先在优先级队列里放入nums1[i] 和 nums2[0]组成的数,
for (int i = 0; i < nums1.size() && i < k; i++) {
pque.emplace(i, 0);
}
while (k-- && !pque.empty()) {
// 当前出队的为最小的组合,a已经放入了,此时a可以匹配到的次小组合为[a, b + 1]
auto& [a, b] = pque.top();
ans.push_back({nums1[a], nums2[b]});
if (b + 1 < nums2.size()) {
pque.emplace(a, b + 1);
}
pque.pop();
}
return ans;
}
};
- 装包裹的最小浪费空间https://leetcode-cn.com/problems/minimum-space-wasted-from-packaging/
// 反向思考,遍历当前的供应商,二分计算当前箱子可以放入的包裹,如果可以放入全部的包裹计算结果
class Solution {
public:
using ull = unsigned long long;
static constexpr ull mod = 1e9 + 7;
int minWastedSpace(vector<int>& packages, vector<vector<int>>& boxes) {
sort(packages.begin(), packages.end());
ull sum = accumulate(packages.begin(), packages.end(), 0LL);
ull cnt, vis;
ull ans = LLONG_MAX;
for (auto& item : boxes) {
cnt = vis = 0;
sort(item.begin(), item.end());
for (auto& box : item) {
auto p = upper_bound(packages.begin(), packages.end(), box) - packages.begin();
if (p < vis) continue;
else {
cnt += (p - vis) * box;
vis = p;
}
if (p == packages.size()) break;
}
if (vis == packages.size())
ans = min(ans, cnt - sum);
}
return ans == LLONG_MAX ? -1 : ans % mod;
}
};