T1 1903. 字符串中的最大奇数
class Solution {
public:
string largestOddNumber(string num) {
string res;
for(int i = num.size(); i >= 0; i--)
{
int x = num[i] - '0';
if(x % 2 == 0)continue;
for(int j = 0; j <= i; j++)
res += num[j];
break;
}
return res;
}
};
T2 1904. 你完成的完整对局数
思路:
- 将字符串转化为数字,将单位统一成分钟。
- 计算对局次数:(代码实现将两种情况(能否整除15)统一)
- 若没有熬夜:
- 若开始时间为15的整数倍,则开始时间不变,否则:
start = start+15 - (start + 15) % 15。- 若结束时间为15的整数倍,则结束时间不变,否则:
finish = finish - (finish % 15)。- 参与对局次数:(finish - start) / 15
- 若熬夜了,则计算一天的总对局次数减去没有参与的对局次数。
- 若开始时间为15的整数倍,则开始时间不变,否则:
start = start - (start % 15)- 若结束时间为15的倍数,则结束时间不变,否则:
finish = finish + 15 - (finish + 15) % 15- 没参与的对局次数:(finish - start) / 15
- 参与的对局次数:24 * 4 - 没参与的对局次数
class Solution {
public:
int numberOfRounds(string startTime, string finishTime) {
int startT = ((startTime[0] - '0') * 10 + startTime[1] - '0') * 60 + (startTime[3] - '0') * 10 + startTime[4] - '0';
int finishT = ((finishTime[0] - '0') * 10 + finishTime[1] - '0') * 60 + (finishTime[3] - '0') * 10 + finishTime[4] - '0';
int res = 0;
if(startT > finishT)
res = 24 * 4 - ( startT + 14 - (startT + 14) % 15 - (finishT - finishT % 15)) / 15;
else
res = (finishT - finishT % 15 - (startT + 14 - (startT + 14) % 15) ) / 15;
return res;
}
};
T3 1905. 统计子岛屿
思路:dfs+标记 o(n2)
- 从公共部分并且没搜过的格子开始搜,只要该格子被搜过,无论其所在的岛屿是否为子岛屿都不必重新再搜一遍。(若为子岛屿,则无需也不应该重复计数,若不为则不用搜)
- 每搜一个格子就对其标记,用一个bool数组存储grid2格子是否被标记,grid1尽量避免修改。
class Solution {
public:
vector<vector<int>>g1, g2;
int n, m;
bool flag;
vector<vector<bool>>st;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
void dfs(int x, int y)
{
for(int i = 0; i < 4; i++)
{
int a = x + dx[i], b = y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= m)continue;
if(st[a][b] || g2[a][b] == 0)continue;
st[a][b] = true;
if(g1[a][b] == 0)flag = false;
dfs(a, b);
}
}
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
g1 = grid1, g2 = grid2;
n = g1.size(), m = g1[0].size();
st = vector<vector<bool>>(n, vector<bool>(m, false));
int res = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
flag = true;
if(g1[i][j] == 1 && g2[i][j] == 1 && st[i][j] == false)
dfs(i, j);
else continue;
if(flag)res++;
}
return res;
}
};
4 1906. 查询差绝对值的最小值
突破点:nums[i]取值[1,100]
思路:前缀和 o(100n)
- 前缀和:统计出整数数组任意前缀1-100的出现次数。
- 查询时通过前缀和数组运算可快速得出查询区间内1-100出现的次数,将其存入数组cnt[]中,遍历一遍该数组统计出两个非0元素的最短下标距离为本次查询结果。
class Solution {
public:
vector<int> minDifference(vector<int>& nums, vector<vector<int>>& queries) {
int s[110000][110] = {0};
int n = nums.size(), m = queries.size();
for(int i = 0; i < n; i++)
for(int j = 1; j <= 100; j++)
{
s[i + 1][j] = s[i][j];
if(j == nums[i])
s[i + 1][j]++;
}
vector<int>res;
for(int i = 0; i < m; i++)
{
int l = queries[i][0], r = queries[i][1];
l++, r++;
int cnt[110];
for(int j = 1; j <= 100; j++)
cnt[j] = s[r][j] - s[l - 1][j];
int last = -1, t = INT_MAX;
for(int j = 1; j <= 100; j++)
{
if(cnt[j])
{
if(last == -1)
last = j;
else
{
t = min(t, j - last);
last = j;
}
}
}
if(t == INT_MAX)t = -1;
res.push_back(t);
}
return res;
}
};