因为经常遇到这类问题,所以做下记录。
【思路】
使用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;
}
};