Problem
Given an array arr
that represents a permutation of numbers from 1
to n
.
You have a binary string of size n
that initially has all its bits set to zero. At each step i
(assuming both the binary string and arr
are 1-indexed) from 1
to n
, the bit at position arr[i]
is set to 1
.
You are also given an integer m
. Find the latest step at which there exists a group of ones of length m
. A group of ones is a contiguous substring of 1
‘s such that it cannot be extended in either direction.
Return the latest step at which there exists a group of ones of length exactly m
. If no such group exists, return -1
.
Example 1:
1 | Input: arr = [3,5,1,2,4], m = 1 |
Example 2:
1 | Input: arr = [3,1,5,4,2], m = 2 |
Constraints:
n == arr.length
1 <= m <= n <= 105
1 <= arr[i] <= n
- All integers in
arr
are distinct.
Analysis
这道题目给出一个数组arr
,包含[1,n]
一共n
个元素,还有一个值m
。题目的操作是从一个长度为n
的全0字符串开始,每次把第arr[i]
上的0改为1,问第几步之后(latest,即最新)存在连续m
个1的substring。这个是一个和子串以及长度有关的题目,但因为我们的操作顺序是按照arr
,也不一定是连续的,所以很难用sliding window。
那么突破口就只能是在长度上做文章了,我们可以用一个数组记录子串的长度,如何用一个数组记录子串长度呢?这里有一个技巧就是只更新leftMost
和rightMost
。比如说0100
,那么对应的长度就是[0, 1, 0, 0]
。如果我把i = 2
改成1,那么就更新为[0, 2, 2, 0]
,更general一点就是,当我改变a = arr[i]
这个位置是,我先找到左边连续1的个数是left = length[a - 1]
,以及右边连续1的个数right = length[a + 1]
。加上当前的这个位置,整个子串的左边界就是a - left
,有边界就是a + right
,更新这两个位置为left + right + 1
。
上面说了怎么维护长度信息,那怎么判断是否存在有长度为m
的连续1子串呢?我们只需要每次反转一个位置后,检查先反转完有没有生成长度为m
的即可,因为要维护latest,所以只要有都更新,从前往后的遍历顺序保证了答案是最近的步骤。
Solution
无。
Code
1 | class Solution { |
Summary
这道题目的技巧之前用的比较少,所以我认为是非常值得总结的,通过维护子串两端的值去维护长度。这道题目的分享到这里,感谢你的支持!