线段合并问题

因为经常遇到这类问题,所以做下记录。

在这里插入图片描述

【思路】
使用length数组维护下标i元素所在的满足要求的区间(连续为1的区间)的长度,只需维护所有1区间两端端点即可。

因为可能遇到边界,所以默认在length两端各加一个哨兵0。

当步骤i的1出现时,下标为x=arr[i],找到该索引x的左右两个下标x-1,x+1的length数组值(即所在1区间的长度),合并区间,通过原区间长度找到x-1所在区间的左端点和x+1所在区间的右端点,维护新长度。

使用哈希表记录长度为len的1区间的数量。

class Solution {
   public:
    int findLatestStep(vector<int>& arr, int m) {
        int memo[100005]{};    // memo[i]表示长度为i的区间数
        int length[100005]{};  // 连续1区间的长度,两端加哨兵0
        int n = arr.size(), res = -1;
        // vector<int> length(n+2);//两端加哨兵0,所以+2
        for (int i = 0; i < n; i++) {
            int x = arr[i];
            int len = length[x - 1] + length[x + 1] + 1;
            if (length[x - 1] != 0) {
                memo[length[x - 1]]--;            //原记录删除
                length[x - length[x - 1]] = len;  //左端点新长度
            }
            if (length[x + 1] != 0) {
                memo[length[x + 1]]--;
                length[x + length[x + 1]] = len;  //右端点新长度
            }
            length[x] = len;  //因为x可能为左右端点,所以也需要维护长度
            memo[len]++;
            if (memo[m] != 0) {
                res = i + 1;
            }
        }
        return res;
    }
};

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值