懒删除|并查集|容斥
lc1201
容斥+二分
一个数,有多少个丑数小于等于该数是可以快速计算出来的
class Solution {
public:
long LCM(long a, long b) {
return a * (b / __gcd(a, b));
}
int nthUglyNumber(int n, int a, int b, int c) {
long ab = LCM(a, b);
long ac = LCM(a, c);
long bc = LCM(b, c);
long abc = LCM(ab, c);
long l = min(a, min(b, c));
long r = 2 * 10e9;
while (l < r) {
long m = l + (r - l) / 2;
long count = m / a + m / b + m / c - m / ab - m / ac - m / bc + m / abc;
if (count < n)
l = m + 1;
else
r = m;
}
}
return l;
}
};
lc926
记录已出现的'1'数量(cnt)
动态计算把当前'0'翻成'1'(dp+1)or
前面'1'全翻成'0'(cnt)的最小值(dp)
最终得让字符串非递减的最少翻转次数
class Solution {
public:
int minFlipsMonoIncr(string s) {
int n=s.size();
if(n==1)return 0;
int cnt=0,dp=0;
if(s[0]=='1') cnt=1;
for(int i=1;i<n;i++)
{
if(s[i]=='1') ++cnt;
else if(s[i]=='0')
dp=min(dp+1,cnt);
}
return dp;
}
};
lc684
class Djset {
public:
vector<int> parent; // 记录节点的根
vector<int> rank; // 记录根节点的深度(用于优化)
Djset(int n): parent(vector<int>(n)), rank(vector<int>(n)) {
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
int find(int x) {
if (x != parent[x]) {
parent[x] = find(parent[x]);
}
return parent[x];
}
bool merge(int x, int y) {
int rootx = find(x);
int rooty = find(y);
if (rootx != rooty) {
if (rank[rootx] < rank[rooty]) {
swap(rootx, rooty);
}
parent[rooty] = rootx;
if (rank[rootx] == rank[rooty]) rank[rootx] += 1;
return false; // 根节点不同,返回false
}
// 根节点相同,返回true
return true;
}
};
class Solution {
public:
vector<int> findRedundantConnection(vector<vector<int>>& edges)
{
int n = edges.size();
Djset ds(n);
for (auto& e : edges)
{
if(ds.merge(e[0] - 1, e[1] - 1))
return {e[0],e[1]};
}
return {};
}
};
拓扑排序
class Solution
{
public:
vector<int> findRedundantConnection(vector<vector<int>>& edges) {
int n = edges.size();
// 邻接表
vector<vector<int> > nei(n);
vector<vector<int> > g(n, vector<int>(n));
vector<int> deg(n, 0);
for (auto& e : edges) {
int a = e[0] - 1;
int b = e[1] - 1;
nei[a].emplace_back(b);
nei[b].emplace_back(a);
g[a][b] = 1;
g[b][a] = 1;
deg[a]++;
deg[b]++;
}
queue<int> q;
for (int i = 0; i < n; i++) {
if (deg[i] == 1) q.push(i);
}
while (!q.empty()) {
int u = q.front();
for (auto& e : nei[u]) {
--deg[u];
--deg[e];
g[u][e] = 0;
g[e][u] = 0;
if (deg[e] == 1) q.push(e);
}
q.pop();
}
for (int i = n-1; i >= 0; i--) {
if (g[edges[i][0]-1][edges[i][1]-1] == 1) {
return {edges[i][0], edges[i][1]};
}
}
return {};
}
};
lc2349
class NumberContainers {
public:
NumberContainers() {
}
void change(int index, int number) {
if (d.contains(index))
{
int old = d[index];
g[old].erase(index);
if (g[old].empty()) {
g.erase(old);
}
}
d[index] = number;
g[number].insert(index);
}
int find(int number) {
return g.contains(number) ? *g[number].begin() : -1;
}
private:
unordered_map<int, int> d;
unordered_map<int, set<int>> g;
};