zoukankan      html  css  js  c++  java
  • leetcode周赛 239

    A:水题,直接枚举即可。

     1 class Solution {
     2 public:
     3     int getMinDistance(vector<int>& nums, int target, int start) {
     4         int res=0,seq=INT_MAX;
     5         for(int i=0;i<nums.size();i++){
     6             if(nums[i]==target&&abs(i-start)<seq){
     7                 seq=abs(i-start);
     8                 res=i;
     9             }
    10         }
    11         return abs(start-res);
    12     } 
    13 };

    B:直接枚举每一段有多少个字母就好了时间(2e19),不过得注意有19位,所以得用ULL来存。

    考试写的dfs版本:

     1 typedef unsigned long long LL;
     2 class Solution {
     3 public:
     4     bool res=false;
     5     LL get(LL l,LL r,string s){
     6         LL res=0;
     7         for(LL i=l;i<=r;i++){
     8             res=res*10+s[i]-'0';
     9         }
    10         return res;
    11     }
    12     void dfs(LL now,LL pre,string& s,LL cnt){
    13         if(now>=s.size()&&cnt>=2){
    14             res=true;
    15             return ;
    16         }
    17         for(LL i=now;i<s.size();i++){
    18             LL num=get(now,i,s);
    19             if((now==0&&num<pre)||num==pre-1){
    20                 dfs(i+1,num,s,cnt+1);
    21             }
    22         }
    23 
    24     }
    25     bool splitString(string s) {
    26         dfs(0,0x3f3f3f3f3f3f3f3f,s,0);
    27         return res;
    28     }
    29 };

    二进制枚举版本:

     1 typedef unsigned long long LL;
     2 class Solution {
     3 public:
     4     bool splitString(string s) {
     5         int n=s.size();
     6         for(int i=1;i < 1<<(n-1);i++){//i是四位,从1开始是至少有一个分割线
     7             unsigned long long x=s[0]-'0';
     8             unsigned long long pre=-1;//补码,全一
     9             bool flag=true;
    10             for(int j=0;j<n-1;j++){
    11                 if(i>>j&1){
    12                     if(pre!=-1&&x!=pre-1){
    13                         flag=false;
    14                         break;
    15                     }
    16                     pre=x;
    17                     x=s[j+1]-'0';
    18                 }else{
    19                     x=x*10+s[j+1]-'0';
    20                 }
    21             }
    22             if(x!=pre-1) flag=false;
    23             if(flag) return true;
    24         }
    25         return false;
    26     }
    27 };

    C:考试的时候想的并不是很明白,复习的时候发现考察逆序对的问题,考试的时候阴差阳错的用冒泡的思想解决了。

    考试的时候的代码:

     1 class Solution {
     2 public:
     3     int getMinSwaps(string num, int k) {
     4         string tnum=num;
     5         for(int i=0;i<k;i++)
     6             next_permutation(tnum.begin(),tnum.end());
     7         int res=0;
     8         for(int i=0;i<num.size();i++){
     9             if(num[i]!=tnum[i]){
    10                 int tar=i+1;
    11                 while(num[i]!=tnum[tar]) tar++;
    12                 for(int j=tar;j>i;j--){
    13                     swap(tnum[tar],tnum[tar-1]);
    14                     tar--;
    15                     res++;
    16                 }
    17             }
    18         }
    19         return res;
    20     }
    21 };

    补题时候的代码:

    还存在一个问题就是如果存在两个相同的元素的话如何对应。

     

    因为只能交换相邻元素,显而易见是第一种,第二种会多出2*s的交换次数。

     1 class Solution {
     2 public:
     3     int getMinSwaps(string a, int k) {
     4         string b=a;
     5         for(int i=0;i<k;i++)
     6             next_permutation(b.begin(),b.end());
     7         int n=b.size();
     8         vector<int> c(n);//存储a中的元素在b中的位置
     9         vector<bool> vis(n);
    10         for(int i=0;i<n;i++){
    11             char ca=a[i];
    12             for(int j=0;j<n;j++){
    13                 if(!vis[j]&&ca==b[j]){
    14                     c[i]=j;
    15                     vis[j]=true;
    16                     break;
    17                 }
    18             }
    19         }
    20         //目的:把c变成正序
    21         //因为n=1e3,冒泡排序即可,若n过大的话,得用归并
    22         int res=0;
    23         for(int i=0;i<n;i++){
    24             for(int j=0;j<n-i-1;j++){
    25                 if(c[j]>c[j+1]){
    26                     swap(c[j],c[j+1]);
    27                     res++;
    28                 }
    29             }
    30         }
    31         return res;
    32     }
    33 };

    D:可以用并查集做,这是个经典模型(参考AcWing疯狂的馒头)

    并查集初始化之后,我们将优先级高的先操作,本题优先级高的就是区间长度短的。

    每次区间操作之后将一个区间删除(方法是让每一个都指向他的后一个元素),同时记录每一个元素对应的答案。

    class Solution {
    public:
        vector<int> p,w;
        vector<int> minInterval(vector<vector<int>>& segs, vector<int>& queries) {
            sort(segs.begin(),segs.end(),[](vector<int>&a,vector<int>&b){
                return a[1]-a[0]+1 < b[1]-b[0]+1;
            });
            const int n=1e7+10;
            p.resize(n+1);
            w.resize(n+1,-1);
            for(int i=0;i<=n;i++) p[i]=i;
            for(auto& s:segs){
                int l=s[0],r=s[1];
                int len=s[1]-s[0]+1;
                while(find(l)<=r){
                    l=find(l);
                    w[l]=len;
                    p[l]=l+1;
                }
            }
            vector<int> res;
            for(auto& q:queries){
                res.push_back(w[q]);
            }
            return res;
        }
        int find(int x){
            if(p[x]!=x)
                p[x]=find(p[x]);
            return p[x];
        }
    };

    但是因为本题n为1e7,时间复杂度为nlogn,会超时

    观察到区间数目和查询数目只有1e5,可以用离散化优化

     1 class Solution {
     2 public:
     3     vector<int> xs;
     4     vector<int> p,w;
     5     vector<int> minInterval(vector<vector<int>>& segs, vector<int>& queries) {
     6         for(auto& s:segs) xs.push_back(s[0]),xs.push_back(s[1]);
     7         for(auto& q:queries) xs.push_back(q);
     8         sort(xs.begin(),xs.end());
     9         xs.erase(unique(xs.begin(),xs.end()),xs.end());
    10         //以上为离散化
    11         sort(segs.begin(),segs.end(),[](vector<int>&a,vector<int>&b){
    12             return a[1]-a[0]+1 < b[1]-b[0]+1;
    13         });
    14         int n=xs.size();
    15         p.resize(n+1);
    16         w.resize(n+1,-1);
    17         for(int i=0;i<=n;i++) p[i]=i;
    18         for(auto& s:segs){
    19             int l=get(s[0]),r=get(s[1]);
    20             int len=s[1]-s[0]+1;
    21             while(find(l)<=r){
    22                 l=find(l);
    23                 w[l]=len;
    24                 p[l]=l+1;
    25             }
    26         }
    27         vector<int> res;
    28         for(auto& q:queries){
    29             res.push_back(w[get(q)]);
    30         }
    31         return res;
    32     }
    33     int find(int x){
    34         if(p[x]!=x)
    35             p[x]=find(p[x]);
    36         return p[x];
    37     }
    38     int get(int x){
    39         return lower_bound(xs.begin(),xs.end(),x)-xs.begin();
    40     }
    41 };
  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14727887.html
Copyright © 2011-2022 走看看