Leetcode双周赛74
将数组划分成相等数对
thinking
哈希表统计数字次数即可
solution
class Solution {
public:
bool divideArray(vector<int>& nums) {
unordered_map<int,int> hash;
for(int &val:nums) {
++hash[val];
}
for(auto &[index,cnt]:hash) {
if(cnt%2==1) return false;
}
return true;
}
};
字符串中最多数目的子字符串
thinking
贪心,我们考虑从到加入的那个字符在哪,对于加入的那个字符来说,我们用a,b来表示给定的模式串,那么插入的字符必定是a,b中字符最小的那个,且将这个字符插在所有的另一个字符的前面或者后面(为简化,我们直接将字符串插在开头或者结尾)。
剩下再统计原来的字符串中出现模式串的个数加上最大a,b的长度即可。
注意:采用下标进行存a,b的位置时,进行计算时,判断两者的下个位置,这个步骤需要用二分进行操作,不然会TLE
solution
class Solution {
public:
long long maximumSubsequenceCount(string t, string p) {
vector<int> a,b;
int n=t.size();
for(int i=0;i<n;++i) {
if(t[i]==p[0]) a.push_back(i);
if(t[i]==p[1]) b.push_back(i);
}
long long ans=0;
int n1=a.size(),n2=b.size();
for(int i=0;i<n1;++i) {
int cnt=upper_bound(b.begin(),b.end(),a[i])-b.begin();
ans+=n2-cnt;
}
return ans+max(n1,n2);
}
};
将数组和减半的最少操作次数
thinking
大根堆模拟
solution
class Solution {
public:
int halveArray(vector<int>& nums) {
priority_queue<double> q;
double sum=0;
for(auto &x:nums) {
sum+=x;
q.push(x);
}
double stay=sum/2.0;
int cnt=0;
while(sum>stay) {
auto num=q.top();
q.pop();
sum-=num/2.0;
q.push(num/2.0);
++cnt;
}
return cnt;
}
};
用地毯覆盖后的最少白色砖块
thinking
来自灵神的智商碾压(link),赛时,我01背包找方案没写出来,换成dfs也没写对。。。。
可以简单地说明贪心是错误的,这一点我在赛时也避开了这一问题。下面我们来按照灵神的思路进行dp操作:
定义\(dp[i][j]\)表示用第i个地毯,覆盖前j块板砖的时候,没被覆盖的白色砖块的最小数目
因此,我们考虑是否用第i条地毯的末尾覆盖第j块地板,我们有状态转移方程:
\[1、不覆盖\\f[i][j]=f[i][j-1]+[floor[j]=='1']\\
2、覆盖\\f[i][j]=f[i-1][j-carpetlen]
\]
solution
class Solution {
public:
int minimumWhiteTiles(string &floor, int n, int carpetLen) {
int m = floor.size();
vector<vector<int>> f(n + 1, vector<int>(m));
f[0][0] = floor[0] % 2;
for (int i = 1; i < m; ++i)
f[0][i] = f[0][i - 1] + floor[i] % 2;
for (int i = 1; i <= n; ++i)
// j < carpetLen 的 f[i][j] 均为 0
for (int j = carpetLen; j < m; ++j)
f[i][j] = min(f[i][j - 1] + floor[j] % 2, f[i - 1][j - carpetLen]);
return f[n][m - 1];
}
};

浙公网安备 33010602011771号