Leetcode】周赛203 查找大小为M的最新分组

题意:

 

给你一个数组 arr ,该数组表示一个从 1 到 n 的数字排列。有一个长度为 n 的二进制字符串,该字符串上的所有位最初都设置为 0 。

 

在从 1 到 n 的每个步骤 i 中(假设二进制字符串和 arr 都是从 1 开始索引的情况下),二进制字符串上位于位置 arr[i] 的位将会设为 1 。

 

给你一个整数 m ,请你找出二进制字符串上存在长度为 m 的一组 1 的最后步骤。一组 1 是一个连续的、由 1 组成的子串,且左右两边不再有可以延伸的 1 。

 

返回存在长度 恰好 为 m 的 一组 1 的最后步骤。如果不存在这样的步骤,请返回 -1 。

 

 

题解:

原本想着就是模拟一下就好了,可是模拟代码在我的codeblocks上跑的没问题,在力扣上运行又是另一种答案,令人头秃

 

 1 #include<stack>
 2 #include<queue>
 3 #include<map>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<algorithm>
 8 #include<vector>
 9 #define fi first
10 #define se second
11 #define pb push_back
12 using namespace std;
13 typedef long long ll;
14 const int maxn=2000+10;
15 const int mod=1e9+7;
16 const double eps=1e-8;
17 const int INF = 0x3f3f3f3f;
18 class Solution {
19 public:
20     int findLatestStep(vector<int>& r, int m) {
21         int len=r.size();
22         int w[100005],v[100005],sum=0;
23         memset(w,0,sizeof(w));
24         memset(v,0,sizeof(v));
25         for(int i=0;i<len;++i)
26         {
27             int aim=r[i];
28             //cout<<aim<<v[aim-1]<<v[aim+1]<<endl;
29             if(v[aim-1]==0 && v[aim+1]==0)
30             {
31                 v[aim]=1;
32                 //cout<<aim<<endl;
33                 w[1]++;
34             }
35             else if(v[aim-1] && v[aim+1]==0)
36             {
37                 w[v[aim-1]]--;
38                 v[aim-v[aim-1]]=v[aim-1]+1;
39                 v[aim]=v[aim-1]+1;
40                 w[v[aim]]++;
41             }
42             else if(v[aim-1]==0 && v[aim+1])
43             {
44                 w[v[aim+1]]--;
45                 v[aim+v[aim+1]]=v[aim+1]+1;
46                 v[aim]=v[aim-1]+1;
47                 w[v[aim]]++;
48             }
49             else
50             {
51                 w[v[aim+1]]--;
52                 w[v[aim-1]]--;
53                 v[aim-v[aim-1]]=v[aim-1]+1+v[aim+1];
54                 v[aim+v[aim+1]]=v[aim+1]+1+v[aim-1];
55                 w[v[aim+1]+v[aim-1]+1]++;
56             }
57             //cout<<w[m]<<"******"<<v[aim+1]<<endl;
58             if(w[m]>0) sum=max(sum,i+1);
59         }
60         if(sum)
61         return sum;
62         else return -1;
63     }
64 };
65 int main()
66 {
67     vector<int>r;
68     int n,m;
69     cin>>n;
70     for(int i=1;i<=n;++i)
71     {
72         int x;
73         cin>>x;
74         r.push_back(x);
75     }
76     cin>>m;
77     Solution s;
78     int ans=s.findLatestStep(r,m);
79     cout<<m<<endl;
80 }
View Code

 

 

 

然后就换一种方式并查集去写,使用v数组来记录每一个位置的父节点,cnt用来记录每个位置的长度,w数组用来记录某个长度连续的1出现次数

没什么好说的,看代码

 

class Solution {
public:
    int v[100010];
    int cnt[100010];
    int w[100010];
    int findp(int x){
        if(v[x]!=x){
            v[x]=findp(v[x]);
        }
        return v[x];
    }
    void merge(int l,int r,int newp){
        if(cnt[l]) v[l]=newp;
        if(cnt[r]) v[r]=newp;
        cnt[newp]=1+cnt[l]+cnt[r];
        w[1+cnt[l]+cnt[r]]++;
    }
    int findLatestStep(vector<int>& arr, int m) {
        int n=arr.size();
        for(int i=0;i<n+2;i++) v[i]=i;
        memset(cnt,0,sizeof(cnt));
        memset(w,0,sizeof(w));
        int res=-1;
        for(int i=0;i<n;i++){
            int l=findp(arr[i]-1),r=findp(arr[i]+1);
            w[cnt[l]]--;
            w[cnt[r]]--;
            merge(l,r,arr[i]);
            if(w[m]>0) res=i+1;
        }
        return res;
    }
};

 

posted @ 2020-08-24 20:22  kongbursi  阅读(176)  评论(0)    收藏  举报