连续段的中数

最优解法

容易发现,答案是满足二分性质的。
二分答案,然后考虑怎么检查mid作为中数是否可行。
令所有大于等于mid的数字都为1,所有小于mid的数字都为-1,则相当于取一段长度大于等于k的数字使得数字和非负。用前缀和的思想,枚举右端点,然后维护的前缀和最小值来得到以为右端点长度大于等于k的连续段数字和最大值。当存在最大值非负的时候表明合法。
时间复杂度
因为只需要维护前缀最小和当前前缀和,所以可以省去前缀和数组的使用,空间复杂度

int solve(int n, int k, vector<int> &a){
    assert(a.size() == n);
    int l = 0, r = 1e9;
    int ans;
    while(l <= r){
        int mid = (r+l)>>1;
        int ps = 0, s = 0, cur = 0;
        for(int i = 0; i < k; ++i)
            if(a[i] >= mid) s ++;
            else s--;
        if(s >= 0){
            ans = mid; l = mid+1; continue;
        }
        int flag = 0;
        for(int i = k; i < n; ++i){
            if(a[i-k] >= mid) cur++;
            else cur--;
            ps = min(ps, cur);
            if(a[i] >= mid) s++;
            else s--;
            if(s-ps >= 0){
                flag = 1; break;
            }
        }
        if(flag) ans = mid, l = mid+1;
        else r = mid-1;
    }return ans;
}
全部评论

相关推荐

废铁汽车人:秋招真是牛鬼蛇神齐聚一堂
点赞 评论 收藏
分享
菜菜咪:1. 可以使用简历网站的模版,美观度会更好一点 2. 邮箱可以重新申请一个,或者用qq邮箱的别名,部分hr可能会不喜欢数字邮箱 3. 项目经历最好分点描述,类似的项目很多,可以参考一下别人怎么写的 4. 自我评价可加可不加,技术岗更看重技术。最后,加油,优秀士兵
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务