文章目录
简介
Leetcode第334场周赛,一共4道题,时间1.5h
第一题:2574. 左右元素和的差值
思路:前缀和
- 前缀和:即统计每一个位置i的
sum(nums[0],nums[1],,,,nums[i-1])
- 这一题具体统计的是i的前缀、后缀和,即求
abs(leftSum[i]-rightSum[i])
代码
vector<int> leftRigthDifference(vector<int> &nums)
{
int *left = new int[nums.size()];
int *right = new int[nums.size()];
memset(left, 0, sizeof(left));
memset(right, 0, sizeof(right));
vector<int> ans;
for (int i = 0; i < nums.size(); i++)
{
if (i == 0)
{
left[i] = 0;
}
else
{
left[i] = left[i - 1] + nums[i - 1];
}
}
for (int i = nums.size() - 1; i >= 0; i--)
{
if (i == nums.size() - 1)
{
right[i] = 0;
}
else
{
right[i] = right[i + 1] + nums[i + 1];
}
}
for (int i = 0; i < nums.size(); i++)
{
ans.push_back(abs(left[i] - right[i]));
}
return ans;
}
第二题:2575. 找出字符串的可整除数组
思路:余数
- 主要考量的是数学中余数相关的知识
- 当前位置
i
代表数字word[i]-'0'
,即为tp
; - 若
i=0
,且tp % m == 0
则i
位置是一个可整除的位置,否则记录余数tpmod = tp % m
; - 若
i > 0
,则若(tp + tpmod * 10)%m==0
,则i
位置是一个可整除的位置,否则更新余数tpmod = (tp + tpmod * 10) % m
代码
vector<int> divisibilityArray(string word, int m)
{
vector<int> ans(word.size(), 0);
long long tp = 0;
long long tpmod = 0;
int lastInd = -1;
for (int i = 0; i < word.size(); i++)
{
tp = word[i] - '0';
long long check = (tp + tpmod * 10) % m;
tpmod = check;
if (tpmod == 0)
{
ans[i] = 1;
lastInd = i;
}
}
return ans;
}
第三题:2576. 求出最多标记下标
思路:双指针
- 排序 + 双指针
- 先将nums从小到大排序
O(nlogn)
- 设置双指针
left、right
,初始化left = 0
,从nums的后半段中找到第一个>= 2*nums[left]
的位置,赋值给right
- Tip: 之所以在后半段找,因为ans最大不会超过nums.size()
- 向右分别移动
left、right
并统计即可
代码
int maxNumOfMarkedIndices(vector<int> &nums)
{
sort(nums.begin(), nums.end());
int n = nums.size();
int ans = 0;
int i;
for (i = n / 2; i < n; i++)
{
if (nums[i] >= 2 * nums[0])
break;
}
int left = 0, right = i;
while (right < n && left < i)
{
if (nums[right] >= 2 * nums[left])
{
ans++;
left++;
}
right++;
}
return ans * 2;
}
第四题:2577. 在网格图中访问一个格子的最少时间
思路:Dijkstra
参考:灵茶山艾府的思路
- dijkstra,设
dist[i][j]
表示到达该位置最短用时 - 核心在与发现:
dist[i][j]和i+j同奇偶,若否则dist[i][j]+=1
dist[i][j] >= grid[i][j]
- 满足上面的限制就可以开始 dijkstra
代码
int moves[5] = {-1, 0, 1, 0, -1};
int minimumTime(vector<vector<int>> &grid)
{
int m = grid.size();
int n = grid[0].size();
// 无法到达
if (grid[0][1] > 1 || grid[1][0] > 1)
return -1;
// 距离方式
int dist[m][n];
// 初始化无限大
memset(dis, 0x3f, sizeof(dis));
dist[0][0] = 0;
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> nodes;
nodes.emplace(0, 0, 0);
while (1)
{
auto [d, i, j] = nodes.top();
nodes.pop();
if (i == m - 1 && j == n - 1)
return d;
else
{
int nd;
for (int k = 0; k <= 3; k++)
{
if (i + moves[k] < 0 || i + moves[k] >= grid.size() || j + moves[k + 1] >= grid[0].size() || j + moves[k + 1] < 0)
continue;
nd = max(d + 1, grid[i + moves[k]][j + moves[k + 1]]);
nd += (nd - (i + moves[k]) - (j + moves[k + 1])) % 2;
if (nd < dist[i + moves[k]][j + moves[k + 1]])
{
dist[i + moves[k]][j + moves[k + 1]] = nd;
nodes.emplace(nd, i + moves[k], j + moves[k + 1]);
}
}
}
}
}