题目1

题意:给一个01串,问是1的连续串长度长还是0的连续串长度长,1返回true,0返回false;

签到题

class Solution {
public:
    bool checkZeroOnes(string s) {
        int n=s.size();
        int a=-1,b=-1,cnt1=0,cnt0=0;
        for(int i=0;i<n;){
        if(s[i]=='1'){
            while(s[i]=='1') cnt1++,i++;
            a=max(a,cnt1);
            cnt1=0;
        }
        if(s[i]=='0'){
            while(s[i]=='0') cnt0++,i++;
            b=max(b,cnt0);
            cnt0=0;
        }
        }
        //cout<<a<<" "<<b;
        if(a>b) return true;
        else return false;
    }
};

题目2

题目描述
图片说明

思路:
数据范围1e5,n方的时间复杂度肯定不行,只能nlogn或n,就想到二分查找速度,然后check一下;

超时代码,***:

class Solution {
public:
    bool chk(int n,vector<int>& dist,double hour){
        double cnt=0;
        for(int i=0;i<dist.size();i++){
        if(i!=dist.size()-1) cnt+=dist[i]/n+1;
            else cnt+=dist[i]*1.0/n;
        }
        if(hour-cnt>=0) return true;
        else return false;
    }
    int minSpeedOnTime(vector<int>& dist, double hour) {
        int l=0,r=1e9;
        int ans=0;
        while(l<r){
        int mid=(l+r)>>1;
        if(chk(mid,dist,hour)) ans=mid,r=mid;
        else l=mid-1;//这个地方应该是mid+1;所以超时
    }
        if(ans) return ans;
        return -1;
    }
};

正确代码:

class Solution {
public:
    double get(vector<int>& dist, int mid) {
        double res = 0;
        for (auto x: dist)
            res += (x + mid - 1) / mid;//因为浮点数不能取余,这里是浮点数向上取整的一个小技巧,加上一个mid,来自y总
        int x = dist.back();
        res -= (x + mid - 1) / mid;
        res += (double)x / mid;
        return res;
    }

    int minSpeedOnTime(vector<int>& dist, double hour) {
        int l = 1, r = 2e7;
        while (l < r) {
            int mid = l + r >> 1;
            if (get(dist, mid) <= hour) r = mid;
            else l = mid + 1;
        }
        if (r == 2e7) return -1;
        return r;
    }
};

题目3

题目描述:

图片说明

思路:
理解题意以后就可以很容易想到,如果是i+a~i+b之间所有的s[i]=='0'就可以找到,就是在一段区间加上一个数,马上就想到了前缀和与差分数组。但是当时不知道怎么写。

代码:

class Solution {
    public boolean canReach(String s, int minv, int maxv) {
        int n = s.length();
        if(s.charAt(n-1) != '0') return false;
        int[] d = new int[200010];
        int sum = 0;
        for(int i = 0; i < n; i ++){
            sum += d[i];
            if(i == 0 || sum > 0 && s.charAt(i) == '0'){
                d[i + minv]++;
                d[i + maxv + 1]--;
            }
        }
        return sum > 0;
    }
}

另外一种思路,dp递推,

代码:

class Solution {
public:
    bool canReach(string str, int a, int b) {
        int n = str.size();
        vector<int> f(n + 1), s(n + 1);
        f[1] = 1;//记录是否能够到达
        s[1] = 1;//f的前缀和
        for (int i = 2; i <= n; i ++ ) {
            if (str[i - 1] == '0' && i - a >= 1) {
                int l = max(1, i - b), r = i - a;
                if (s[r] > s[l - 1]) f[i] = 1;//s[r]-s[l-1]求l~r的区间和。
            }
            s[i] = s[i - 1] + f[i];
        }
        return f[n];
    }
};