六月集训(第17天)—广度优先搜索
广度优先搜索
1. 2059. 转化数字的最小运算数
思路:
用数组中的数对start进行三种不同的操作,获得0~1000之间的数字,找到结果后返回。时间复杂度$O(n * C)$, $C = 1000$生成数字的范围。
struct MY_NUM {
int num;
int step;
};
class Solution {
public:
int minimumOperations(vector<int>& nums, int start, int goal) {
int nums_size = nums.size(), i;
queue<MY_NUM> q;
bool vis[1010];
memset(vis, 0, sizeof(vis));
q.push({start, 0});
vis[start] = true;
while (!q.empty()) {
MY_NUM now = q.front();
q.pop();
for (i = 0; i < nums_size; ++i) {
int temp = now.num + nums[i];
if (temp == goal) return now.step + 1;
if (temp >= 0 && temp <= 1000 && !vis[temp]) {
vis[temp] = true;
q.push({temp, now.step + 1});
}
temp = now.num - nums[i];
if (temp == goal) return now.step + 1;
if (temp >= 0 && temp <= 1000 && !vis[temp]) {
vis[temp] = true;
q.push({temp, now.step + 1});
}
temp = now.num ^ nums[i];
if (temp == goal) return now.step + 1;
if (temp >= 0 && temp <= 1000 && !vis[temp]) {
vis[temp] = true;
q.push({temp, now.step + 1});
}
}
}
return -1;
}
};
2. 690. 员工的重要性
思路:
利用unordered_map将id直接映射该员工的信息结点指针,方便查询。利用队列搜索每个员工的员工,搜过过程中累加重要性。
/*
// Definition for Employee.
class Employee {
public:
int id;
int importance;
vector<int> subordinates;
};
*/
class Solution {
public:
int getImportance(vector<Employee*> employees, int id) {
queue<int> q;
unordered_map<int, Employee*> worker;
int n = employees.size(), i;
int ans = 0;
for (i = 0; i < n; ++i) {
worker[employees[i]->id] = employees[i]; // 用id直接映射该员工的信息结点指针
}
ans += worker[id]->importance;
q.push(id);
while (!q.empty()) {
int now_id = q.front();
q.pop();
int new_id;
int now_size = worker[now_id]->subordinates.size(), j;
for (j = 0; j < now_size; ++j) {
new_id = worker[now_id]->subordinates[j];
Employee *temp = new Employee();
temp = worker[new_id];
ans += temp->importance; // 累加重要性
q.push(new_id); // 将now_id的直属员工加入队列
}
}
return ans;
}
};
3. 672. 灯泡开关 Ⅱ
思路:
利用数学方法找规律:一共有四种方法,之间可以相互组合
首先讨论四种方法之间的组合:
某种操作出现奇数次相当于出现1次,出现偶数次相当于没有出现
AB == C AC == B BC == A
1) presses = 0 操作0次只能有全灭一种情况
2) presses = 1 操作一次有 A B C D四种情况
3) presses = 2 前三种操作出现的组合只有 0 A B C 共四种种情况,加上第四种操作,总的操作可能有 0 A B C D AD BD CD共八种可能。
下面分类讨论
(1) n == 0 ,ans = 1
(2) n == 1 ,ans = 2
0 1
(3) n == 2
此时A, C, D的效果相同都是让i==1位置上的灯翻转
3.1) presses == 1 ans = 3;
不能实现全灭
3.2) presses >= 2 ans = 4;
(4) n >= 3
4.1) presses == 1 ans = 3;
A B C D四种情况
4.2) presses == 2 ans = 7;
0 A B C AD BD CD此时无法通过组合实现单纯的D情况,共七种情况;
4.3) presses == 3 ans = 8;
0 A B C D AD BD CD八种情况均可以组合获得。
class Solution {
public:
int flipLights(int n, int presses) {
if (presses == 0) return 1;
if (n == 1) return 2;
if (n == 2) {
if (presses == 1) return 3;
if (presses >= 2) return 4;
}
if (n >= 3) {
if (presses == 1) return 4;
else if (presses == 2) return 7;
else return 8;
}
return 1; // n == 0
}
};

浙公网安备 33010602011771号