2974. 最小数字游戏
2975. 移除栅栏得到的正方形田地的最大面积
2976. 转换字符串的最小成本 I
2977. 转换字符串的最小成本 II
这题看懂题意就好,可以结合示例模拟一下,你就会发现规律,本质就是将数组排序,然后将相邻两个数字交换一下即可
代码如下
class Solution {
public:
vector numberGame(vector& nums) {
sort(nums.begin(),nums.end());
int n=nums.size();
for(int i=0;i
这题就是单纯暴力求解两个栏杆之间的距离,代码如下
class Solution {
public:
unordered_set f(vector&a,int mx){
a.push_back(1);
a.push_back(mx);
sort(a.begin(),a.end());
unordered_sets;
for(int i=0;i& hFences, vector& vFences) {
auto h=f(hFences,m);
auto v=f(vFences,n);
int ans=0;
for(auto x:h){
if(v.count(x))
ans=max(ans,x);
}
return ans?1LL*ans*ans%1000000007:-1;
}
};
这题的关键是你的看出来这是求全源最短路问题,题目要求将source变成target的最小成本,也就是字符之间的相互转换的代价最小,同时,题目允许出现一个字符到另一个字符中间有其他"中转站"的情况,很明显在考Floyd算法,代码如下
class Solution {
public:
long long minimumCost(string source, string target, vector& original, vector& changed, vector& cost) {
map,int>mp;
int n=source.size();
int m=original.size();
vector>g(26,vector(26,-1));
for(int i=0;i
这题和上一题一样,只是重字符之间的转化,改成了字符串之间的转换,我们依旧是用Floyd算法,但问题是我们如何标识和处理字符串,这里要用到字典树(208. 实现 Trie (前缀树) 标准的字典树模型,不认识的可以先去写这道题)。
同时,这题还需要用到dp,而且题目都帮我们降低难度了,说我们每次修改的区域不能出现重合。
状态定义为dp[i]表示以i为起始位置的字符串从source变成target的最小代价
dp[i]=min( dp[j] + g[i][j] ) 前提是区间[i,j]内的source字符串能变成target对应部分的字符串
代码如下
struct Node{
Node*child[26]={0};
int sid=-1;//用来标识字符串,表示以该结点为结尾的字符串序号
};
class Solution {
public:
long long minimumCost(string source, string target, vector& original, vector& changed, vector& cost) {
Node*root=new Node();
int sid=0;
//字典树
functionput=[&](string s)->int{
Node*node=root;
for(auto e:s){
int x=e-'a';
if(node->child[x]==nullptr)
node->child[x]=new Node();
node=node->child[x];
}
if(node->sid==-1)
node->sid=sid++;
return node->sid;
};
int n=original.size();
vector>g(2*n,vector(2*n,-1));
for(int i=0;imemo(m,-1);
// functiondfs=[&](int i)->long long{
// if(i>=m) return 0;
// auto& res=memo[i];
// if(res!=-1) return res;
// res=LLONG_MAX/2;
// if(source[i]==target[i])//不要改
// res=dfs(i+1);
// Node*q=root,*p=root;
// for(int j=i;jchild[source[j]-'a'];
// p=p->child[target[j]-'a'];
// if(q==nullptr||p==nullptr)
// break;
// if(q->sid<0||p->sid<0)
// continue;
// int d=g[q->sid][p->sid];
// if(d!=-1)
// res=min(res,dfs(j+1)+d);
// }
// return res;
// };
// long long ans = dfs(0);
// return ans < LLONG_MAX / 2 ? ans : -1;
//递推写法
vectordp(m+1);
for(int i=m-1;i>=0;i--){
long long res=LLONG_MAX/2;
if(source[i]==target[i])//不要改
res=dp[i+1];
Node*q=root,*p=root;
for(int j=i;jchild[source[j]-'a'];
p=p->child[target[j]-'a'];
if(q==nullptr||p==nullptr)
break;
if(q->sid<0||p->sid<0)
continue;
int d=g[q->sid][p->sid];
if(d!=-1)
res=min(res,dp[j+1]+d);
}
dp[i]=res;
}
return dp[0]