第 33 场双周赛
关注"Grand Theft Algorithm",带你吃透算法题!
## 题目1:[5479. 千位分隔数](https://leetcode-cn.com/problems/thousand-separator/)
思路:模拟
签到题,把整数变为字符串,从后向前遍历,每三位加点即可。
代码:
class Solution {
public:
string thousandSeparator(int n) {
string s = to_string(n); //转为字符串
reverse(s.begin(), s.end());
string res;
int len = s.size();
for (int i = 0; i < len; i++) {
res += s[i];
if (i % 3 == 2 && i + 1 != len) res += ".";
}
reverse(res.begin(), res.end());
return res;
}
};
复杂度分析:
简单遍历,时间复杂度O(N);
记录结果字符串,空间复杂度O(N)。
关注"Grand Theft Algorithm",带你吃透算法题!
题目2:5480. 可以到达所有点的最少点数目
思路:字符串遍历
签到题2。
要求最少的点能到达其他所有点,找到所有入度为0的点即可。
代码:
class Solution {
public:
vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) {
vector<int> u(n);
for (auto &e : edges) {
int x = e[0], y = e[1];
u[y] ++;
}
vector<int> res;
for (int i = 0; i < n; ++i)
if (u[i] == 0) res.push_back(i);
return res;
}
};
复杂度分析:
遍历数组,时间复杂度为O(N);
空间复杂度为O(N)。
关注"Grand Theft Algorithm",带你吃透算法题!
题目3:5481. 得到目标数组的最少函数调用次数
思路:简单遍历
倒推,求最少的“单个元素减一”和“全部元素除2”的操作次数使得数组元素全部变为0。
不妨一个一个元素考虑:
每一个元素的减1过程都是单独进行的,所以如果当前元素是奇数,就必须要进行减一操作,最后需要将所有元素的减一操作次数相加;
而每个元素的除2操作是整个数组共同进行的,而某一个元素变成0之后,其他元素再怎么折腾,不管多少次除2操作都不会对这个元素有影响,所以最后只需要求出所有元素的除二次数的最大值。
扫描二维码关注公众号,回复:
12681149 查看本文章

代码:
class Solution {
public:
int minOperations(vector<int>& nums) {
int res = 0, pos = 0;
for(int x : nums) {
int now = 0;
while(x) {
if(x % 2 == 1) {
res++; // 减1次数
x--;
} else {
now++;
x /= 2;
}
}
pos = max(pos, now); // 除2次数
}
res += pos;
return res;
}
};
复杂度分析:
数组遍历,时间复杂度为O(N);
维护两个变量,空间复杂度为O(1)。
关注"Grand Theft Algorithm",带你吃透算法题!
题目4:5482. 二维网格图中探测环
思路:深度优先搜索
要在二维地图里寻找某种不重复路径,且需要判断全部路径中是否有满足条件(即成环)的路径,用深度优先搜索。
判断环路,说明最后要回到之前遍历过的某一点,为了防止最后两个点来回搜索,要在参数中记录父节点(即探索当前位置的前一个位置)。
实现细节:
深搜过程中,首先判断拓展节点与父节点是否相同,若相同说明搜索在两个点来回进行,直接pass掉。
其次判断拓展节点是否已经遍历过,若遍历过且不为父节点,说明找到了之前遍历过的某一点,满足成环条件,返回 t r u e true true 。
若没有遍历过,则对拓展节点进行新一次的深度优先搜索。若所有拓展节点都深搜完成且未找到成环路径,则返回 f a l s e false false 。
代码:
class Solution {
public:
int n, m;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
bool in_grid(int x, int y) {
return x >= 0 && x < n && y >= 0 && y < m;
}
bool dfs(int x, int y, int fx, int fy, vector<vector<char>>& grid, vector<vector<bool>>& visit) {
visit[x][y] = true;
for(int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if(nx == fx && ny == fy) {
continue;
}
if(in_grid(nx, ny) && grid[nx][ny] == grid[x][y]) {
if(visit[nx][ny]) {
return true;
}
if(dfs(nx, ny, x, y, grid, visit)) {
return true;
}
}
}
return false;
}
bool containsCycle(vector<vector<char>>& grid) {
n = grid.size();
m = grid[0].size();
vector<vector<bool>> visit(n, vector<bool>(m, 0));
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(!visit[i][j]) {
if(dfs(i, j, -1, -1, grid, visit)) {
return true;
}
}
}
}
return false;
}
};
复杂度分析:
深度优先搜索,总时间复杂度为O(NM);
维护遍历过程记录表,空间复杂度为O(NM)。