leetcode第105场双周赛 3 - DP 4 - 并查集 + 思维 + 数学
6394. 字符串中的额外字符
使用动态规划求解
详见代码:
class Solution {
public:
int minExtraChar(string s, vector<string>& ct) {
int n=s.size();
vector<int> dp(n+1,n);
dp[0]=0;
for(int i=0;i<n;++i){
for(auto a:ct){
if(s.substr(i,a.size())==a){
dp[i+a.size()]=min(dp[i+a.size()],dp[i]);//以匹配上的字符串转移状态
}
}
dp[i+1]=min(dp[i+1],dp[i]+1);//假设当前位置无法匹配字典中的字符串
}
return dp[n];
}
};
2709. 最大公约数遍历
朴素的判断两两之间是否相连,TLE
我们可以首先预处理出所有数的质因数,之后将这些数与质因数构成并查集,最后判断是不是构成的完整的一个并查集即可
const int maxm=1e5+5;
vector<int> fac[maxm+5];
bool f=false;
int root[maxm<<1];
class Solution {
public:
void pre(){//预处理范围内的数,初步建立值与因子之间的关系
if(!f)
for(int i=2;i<=maxm;++i){
if(fac[i].empty()){
for(int j=i;j<=maxm;j+=i)
fac[j].push_back(i);
}
}
f=true;
for(int i=0;i<maxm<<1;++i) root[i]=i;//并查集初始化
}
bool canTraverseAllPairs(vector<int>& nums) {
pre();
int n=nums.size();
function<int(int)> findroot = [&](int x) {
if (root[x] != x) root[x] = findroot(root[x]);
return root[x];
};
for(int i=0;i<n;++i){//对每个数的因子进行连接
for(int p:fac[nums[i]]){
int x=findroot(i),y=findroot(n+p);
if(x==y) continue;
root[x]=y;
}
}
unordered_set<int> st;
for(int i=0;i<n;++i) st.insert(findroot(i));
return st.size()==1;
}
};
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17437654.html