[研究生冲刺][算法实习生]LeetCode刷题日记(Day4)【欢迎关注,一起努力!Cheers!】
1562. 查找大小为 M 的最新分组(第203场周赛issue 3)
思路:
使用并查集来管理长度问题,然后在主函数中如果出现合并则将旧的长度数组length减一,然后最后将新的length加一即可。要注意的是每次对length操作时,要将索引的祖先节点作为索引,即使用Find函数。
算法的复杂度:
算法的时间复杂度近似为O(n),因为在并查集中使用了压缩路径~(实际上是默认查操作为1 op简化复杂度计算)~。算法的空间复杂度为O(n)。
代码:
class Solution {
public:
int Find(vector<int>& father, int s)
{
int temp = s;
while (s != father[s])
{
s = father[s];
}
father[temp] = s;
return s;
}
int Union(vector<int>& father, vector<int>& count, int a, int b)
{
int fa = Find(father, a);
int fb = Find(father, b);
father[fb] = fa;
count[fa] += count[fb];
return count[fa];
}
int findLatestStep(vector<int>& arr, int m) {
int n = arr.size();
vector<bool> str(n + 1, 0);
vector<int> length(n + 1, 0);
vector<int> father(n + 1);
vector<int> count(n + 1, 1);
int res = -1;
for (int i = 1; i <= n; ++i)
{
father[i] = i;
}
for (int i = 1; i <= n; ++i)
{
int pos = arr[i - 1];
str[pos] = 1;
int len = 1;
if (pos > 1 && str[pos - 1])
{
--length[count[Find(father,pos - 1)]];
len = Union(father, count, pos, pos - 1);
}
if (pos < n && str[pos + 1])
{
--length[count[Find(father, pos + 1)]];
len = Union(father, count, pos, pos + 1);
}
++length[count[pos]];
if (length[m] > 0)
res = i;
}
return res;
}
};
结果