1. 程式人生 > 實用技巧 >Leetcode】周賽203 查詢大小為M的最新分組

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;
    }
};