zoukankan      html  css  js  c++  java
  • 5497. 查找大小为 M 的最新分组

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

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

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

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

    示例 1:

    输入:arr = [3,5,1,2,4], m = 1
    输出:4
    解释:
    步骤 1:"00100",由 1 构成的组:["1"]
    步骤 2:"00101",由 1 构成的组:["1", "1"]
    步骤 3:"10101",由 1 构成的组:["1", "1", "1"]
    步骤 4:"11101",由 1 构成的组:["111", "1"]
    步骤 5:"11111",由 1 构成的组:["11111"]
    存在长度为 1 的一组 1 的最后步骤是步骤 4 。
    示例 2:

    输入:arr = [3,1,5,4,2], m = 2
    输出:-1
    解释:
    步骤 1:"00100",由 1 构成的组:["1"]
    步骤 2:"10100",由 1 构成的组:["1", "1"]
    步骤 3:"10101",由 1 构成的组:["1", "1", "1"]
    步骤 4:"10111",由 1 构成的组:["1", "111"]
    步骤 5:"11111",由 1 构成的组:["11111"]
    不管是哪一步骤都无法形成长度为 2 的一组 1 。
    示例 3:

    输入:arr = [1], m = 1
    输出:1
    示例 4:

    输入:arr = [2,1], m = 2
    输出:2

    提示:

    n == arr.length
    1 <= n <= 10^5
    1 <= arr[i] <= n
    arr 中的所有整数 互不相同
    1 <= m <= arr.length

    平衡树写法

    维护连续1的区间,每一个结点x设置l[x]和r[x],在每一个操作进行时维护连续1的区间。

    class Solution {
    public:
        //维护连续1的线段长度
        vector<int> l, r;
        int findLatestStep(vector<int>& arr, int m) {
            int n = arr.size();
            l.resize(n + 2), r.resize(n + 2);
            
            int cnt = 0, res = -1;
            for(int i = 0; i < n; i ++){
                int x = arr[i];
                if(l[x - 1] && r[x + 1]){
                    if(x - l[x - 1] == m) cnt --;
                    if(r[x + 1] - x == m) cnt --;
                    r[l[x - 1]] = r[x + 1];
                    l[r[x + 1]] = l[x - 1];
                    if(r[x + 1] - l[x - 1] + 1 == m) cnt ++;
                }else if(r[x + 1]){
                    if(r[x + 1] - x == m) cnt --;
                    l[r[x + 1]] = x;
                    r[x] = r[x + 1];
                    if(r[x + 1] - x + 1 == m) cnt ++;
                }else if(l[x - 1]){
                    if(x - l[x - 1] == m) cnt --;
                    r[l[x - 1]] = x;
                    l[x] = l[x - 1];
                    if(x - l[x - 1] + 1 == m) cnt ++;
                }else{
                    r[x] = l[x] = x;
                    if(m == 1) cnt ++;
                }
                
                if(cnt) res = i + 1;
            }
            
            return res;
        }
    };
    

    并查集写法

    一样的原理

    class Solution {
    public:
        static const int N = 100010;
        int p[N], c[N];
        
        int find(int x){
            if(p[x] != x) x = find(p[x]);
            return p[x];
        }
        
        int findLatestStep(vector<int>& arr, int m) {
            int n = arr.size();    
            for(int i = 1; i <= n; i ++) p[i] = i;
            
            int cnt = 0, res = -1;
            for(int i = 0; i < n; i ++){
                int x = arr[i];
                int l = find(x - 1), r = find(x + 1);
                
                if(c[l] && c[r]){
                    if(c[l] == m) cnt --;
                    if(c[r] == m) cnt --;
                    p[r] = p[x] = l;
                    c[l] += c[r] + 1;
                    if(c[l] == m) cnt ++; 
                    
                }else if(c[l]){
                    if(c[l] == m) cnt --;
                    p[x] = l;
                    c[l] ++;
                    if(c[l] == m) cnt ++;
                    
                }else if(c[r]){
                    if(c[r] == m) cnt --;
                    p[x] = r;
                    c[r] ++;
                    if(c[r] == m) cnt ++;
                }else{
                    c[x] ++;
                    if(m == 1) cnt ++;
                }
                
                if(cnt)
                    res = i + 1;
            }
            return res;
        }
    };
    
  • 相关阅读:
    剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前
    剑指offer编程题Java实现——面试题13在O(1)时间内删除链表节点
    剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
    剑指offer编程题Java实现——面试题12打印1到最大的n位数
    《深入理解JAVA虚拟机》——学习笔记
    剑指offer编程题Java实现——面试题11数值的整数次方
    剑指offer编程题Java实现——面试题10二进制中1的个数
    剑指offer编程题Java实现——面试题9斐波那契数列
    剑指offer编程题Java实现——面试题8旋转数组的最小数字
    mysql高可用集群——MHA架构
  • 原文地址:https://www.cnblogs.com/tomori/p/13550021.html
Copyright © 2011-2022 走看看