这周leetcode的题还是比较简单的,最近期末了可能更新会变慢,祝大家期末都能考好

希望我期末不挂科!这样我假期就可以好好打cf了,上大分!

A

map,水水水

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
map<int,int>mp1;
map<int,int>mp2;
public:
vector<int> findIntersectionValues(vector<int>& nums1, vector<int>& nums2) {
vector<int>ans(2,0);
for(auto &i:nums1)mp1[i]=1;
for(auto &i:nums2)mp2[i]=1;

for(auto &i:nums1){
if(mp2[i])ans[0]+=mp2[i];
}
for(auto &i:nums2){
if(mp1[i])ans[1]+=mp1[i];
}
return ans;
}
};

B

很简单,观察可得如果有一个相邻元素近似的子串,我们一定是隔两个操作一个,所以只用记录长度然后ans+cnt/2就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int removeAlmostEqualCharacters(string word) {
int len=word.size();
int ans=0,cnt=1;
for(int i=1;i<len;i++){
while(abs(word[i]-word[i-1])<=1){
cnt++;
i++;
}
ans+=cnt/2;
cnt=1;
}
return ans;
}
};

C

滑动窗口,拿一个map记录元素出现次数,每加进一个元素看看新加的元素的次数是否超过k,while超过就pop,过程中最大的队列长度就是要求的答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
map<int,int>mp;
queue<int>q;
public:
int maxSubarrayLength(vector<int>& nums, int k) {
int ans=0;
for(auto &i:nums){
q.push(i);
mp[i]++;
while(q.size()&&mp[i]>k){
mp[q.front()]--;
q.pop();
}
int len=q.size();
ans=max(ans,len);
}
return ans;
}
};

D

别看了,没做出来。TxT

想到了floyd但是不太会状态压缩和实现,但是能想到floyd的这种中间节点的桥梁性我觉得说明我对算法的理解也是有上升的。

可惜现在还不太会做,中午听完灵神的思路回来就更新!


第一个双百!!

首先观察数据范围 n是1-10 说明用到的算法时间复杂度可以很高

观察这个过程,非常明显的floyd特性,但是需要想到的是如何表示每一个子集以及选or不选的状态表示呢?

用到的就是状态压缩的模拟

观察到一个很妙的特性,n的子集有2的n次方个,恰好就是二进制位数为n可表示的数据范围,从0一直到1<<n就可以取到n的所有子集,

这里是是<(1<<n)。**如果n位全取1,则最大为1<<n-1,如果全取0就是0,所以我们要枚举的范围就是0-1<<n-1。**接下来要注意的是floyd。首先是邻接矩阵存边,因为会有重边所以取最小值。**别忘记初始化!!**在存储的时候要想到,如果一个点被去掉(未选中)那么所有边都无法到达它,所以将所有可以取到的边复制到d数组就可以。接下来就是floyd的主题,在每一层循环里都要判断当前取得i,j,k都是可选中的点。最后遍历d数组,也要确定都是可取得的点,如果有距离大于maxdistance,那么就返回false,否则返回true。ans累加每一个子集的check结果就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Solution {
using i64=long long;
int d[15][15],a[15][15];
public:
int numberOfSets(int n, int md, vector<vector<int>>& roads) {
memset(a,0x3f,sizeof a);
for(int i=0;i<n;i++){
a[i][i]=0;
}
for(auto &e:roads){
int x=e[0],y=e[1],w=e[2];
a[x][y]=min(a[x][y],w);
a[y][x]=min(a[y][x],w);
}
auto check=[&](int s)->bool{
for(int i=0;i<n;i++){
if((s>>i)&1){
for(int j=0;j<n;j++){
d[i][j]=a[i][j];
}
}
}
for(int k=0;k<n;k++){
if(((s>>k)&1)==0)continue;
for(int i=0;i<n;i++){
if((s>>i&1)==0)continue;
for(int j=0;j<n;j++){
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
}
for(int i=0;i<n;i++){
if(((s>>i)&1)==0)continue;
for(int j=0;j<n;j++){
if((s>>j)&1&&d[i][j]>md)return false;
}
}
return true;
};
int ans=0;
for(int s=0;s<(1<<n);s++){
ans+=check(s);
}
return ans;
}
};