第60场LeetCode双周赛
心情
题目在此
双周赛都补题
第一题(找到数组的中间位置)
题目意义不难理解。
class Solution {
public:
int findMiddleIndex(vector<int>& nums) {
int sum = 0; //右边和
for (int x: nums) sum += x;
int t = 0; //左边和
int i = 0;
for (int x: nums){
if (sum - x == t) return i;
++i; //枚举每一个位置,从而计算每个位置左右两边的和
sum -= x;
t += x;
}
return -1;
}
};
第二题(找到所有的农场组)
数据范围小,可以直接暴力。
class Solution {
public:
vector<vector<int>> findFarmland(vector<vector<int>>& land) {
vector<vector<int>> lv;
int n = land.size(),m = land[0].size();
vector<vector<bool> > vis(n,vector<bool>(m,false));
for (int i = 0; i < n; i ++){
for (int j = 0; j < m;j ++){
if (vis[i][j]||!land[i][j])continue;
int x1 = i,y1 = j,x2,y2,k;
for (k = y1; k < m; k ++)if (!land[i][k])break;
y2 = k-1;
for (k = x1; k < n; k ++)if (!land[k][j])break;
x2 = k -1;
for (k = x1; k <= x2; k ++)
for (int z = y1; z <= y2; z ++)
vis[k][z] = true;
lv.push_back(vector<int>{x1,y1,x2,y2});
}
}
return lv;
}
};
第三题(树上的操作)
挺好的题目,值得回顾。
class LockingTree {
public:
vector<int> p;
vector<vector<int>> g;
vector<int> user;
int n;
LockingTree(vector<int>& parent) {
p = parent;
n = p.size();
g.resize(n);
user = vector<int>(n,-1);
for (int i = 1; i < n; i ++)
g[p[i]].push_back(i); //建图
}
bool lock(int num, int u) {
if (user[num] != -1)return false; //有锁不能再上锁
user[num] = u; //上锁
return true;
}
bool unlock(int num, int u) {
if (user[num] != u)return false; //查看是不是u上的num锁
user[num] = -1; //解锁
return true;
}
int dfs(int num){
int cnt = 0;
if (user[num] != -1){
user[num] = -1;
cnt ++;
}
for (auto son : g[num]){
cnt += dfs(son);
}
return cnt;
}
bool upgrade(int num, int u) {
if (user[num] != -1)return false; //如果有锁就直接退出
for (int i = p[num]; i != -1; i = p[i]) //查看父节点是否有锁
if (user[i] != -1)return false;
int cnt = dfs(num); //dfs搜索子节点,判断是否num的子节点有被上锁的
if (!cnt)return false;
user[num] = u; //上面条件满足,那就可以给num上锁
return true;
}
};