6369 左右元素和的差值
前缀和
class Solution {
public:
vector<int> leftRigthDifference(vector<int>& nums)
{
int n = nums.size();
vector<int> pre_sum(n + 2);
for(int i = 0; i < n; i ++)
pre_sum[i + 1] = pre_sum[i] + nums[i];
pre_sum[n + 1] = pre_sum[n];
vector<int> ans(n);
for(int i = 0; i < n; i ++)
ans[i] = std::abs(pre_sum[i] - pre_sum[n + 1] + pre_sum[i + 1]);
return ans;
}
};
6368 找出字符串的可整除数组
class Solution {
public:
vector<int> divisibilityArray(string word, int m)
{
int n = word.length();
vector<int> ans(n);
long long cur = 0;
for(int i = 0; i < n; i ++)
{
cur *= 10;
cur %= m;
cur += word[i] - '0';
cur %= m;
if(cur == 0) ans[i] = 1;
}
return ans;
}
};
6367 求出最多标记下标
题目描述:
给你一个下标从 0 开始的整数数组 nums 。
一开始,所有下标都没有被标记。你可以执行以下操作任意次:
- 选择两个 互不相同且未标记 的下标 i 和 j ,满足 2 * nums[i] <= nums[j] ,标记下标 i 和 j 。
请你执行上述操作任意次,返回 nums 中最多可以标记的下标数目。
思路:
如果对原数组进行排序,假设最多被标记的数有m对,则有这2*m个数必然是排序后数组的前m个和后m个(做题时的总结能力实在太重要了,这个当时做的时候自己也没想到)。故只需要对排序后的数组进行搜索这个m即可(其中第一个数与倒数第m个数配对标记、最后一个数与第m个数配对标记),可以通过二分法对数组前半段进行搜索,但这里主要的时间复杂度在于排序,搜索没有决定性影响。
int maxNumOfMarkedIndices(vector<int>& nums)
{
int n = nums.size();
sort(nums.begin(), nums.end());
// 二分法查找
int l = 0, r = n / 2, mid;
while(l <= r)
{
mid = (l + r) / 2;
bool sign = true;
for(int i = 0; i < mid; i ++)
if(2 * nums[i] > nums[n + i - mid])
sign = false;
if(sign) l = mid + 1;
else r = mid - 1;
}
return r * 2;
}
6366
题目描述:
给你一个 m x n 的矩阵 grid ,每个元素都为 非负 整数,其中 grid[row][col] 表示可以访问格子 (row, col) 的 最早 时间。也就是说当你访问格子 (row, col) 时,最少已经经过的时间为 grid[row][col] 。
你从 最左上角 出发,出发时刻为 0 ,你必须一直移动到上下左右相邻四个格子中的 任意 一个格子(即不能停留在格子上)。每次移动都需要花费 1 单位时间。
请你返回 最早 到达右下角格子的时间,如果你无法到达右下角的格子,请你返回 -1 。
思路:
- 只有当grid[0][1]和grid[1][0]都大于1时,才会无法到达并返回-1,其他情况下都可以通过来回移动等待时间限制
- 到达任意坐标的时间的最小值,必然大于等于到达其相邻坐标的时间+1
- 故到达一个坐标的最短时间,是该坐标时间限制与其相邻坐标到达时间+1这两者的最大值,但是同时,其奇偶性必须与横纵坐标的和一致
- 在此基础上,使用广度优先搜索(Dijkstra)
class Solution {
public:
typedef pair<int, pair<int, int>> piii;
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
struct cmp{
bool operator()(piii& a, piii& b) {
return a.first > b.first;
}
};
int minimumTime(vector<vector<int>>& grid)
{
if(grid[0][1] > 1 && grid[1][0] > 1) return -1;
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dp(m, vector<int>(n, 0));
priority_queue<piii, vector<piii>, cmp> bfs_queue;
bfs_queue.push({0, {0, 0}});
pair<int, pair<int, int>> cur_pos;
while(!bfs_queue.empty())
{
cur_pos = bfs_queue.top();
bfs_queue.pop();
for(int i = 0; i < 4; i ++)
{
int new_x = cur_pos.second.first + directions[i][0], new_y = cur_pos.second.second + directions[i][1];
if(new_x < m && new_x >= 0 && new_y < n && new_y >= 0)
{
int new_dis = std::max(cur_pos.first + 1, grid[new_x][new_y]); // 到达时间必须大于等于限制的时间
new_dis += (new_dis + new_x + new_y) % 2; // 奇偶性需要与坐标相同
if(new_dis < dp[new_x][new_y] || dp[new_x][new_y] == 0)
{
dp[new_x][new_y] = new_dis;
if(new_x == m - 1 && new_y == n - 1) return new_dis;
bfs_queue.push({new_dis, {new_x, new_y}});
}
}
}
}
return -1;
}
};
参考:
https://leetcode.cn/circle/discuss/ldt5CI/